【问题标题】:Check equality of a ENUM value with a String in JAVA在 JAVA 中检查 ENUM 值与字符串的相等性
【发布时间】:2015-04-02 12:27:01
【问题描述】:

我知道正确的方法是Days.MONDAY.name().equals(day)。但我想知道为什么Days.MONDAY.equals(day) 在两者都打印 MONDAY 时会失败。

我知道我缺少 equals() 和 toString() 的一些东西。我想清楚地知道它是什么。

String day = "MONDAY";
System.out.println("main().Days.MONDAY : " + Days.MONDAY); // Prints MONDAY
System.out.println("main().day : " + day);// Prints MONDAY

System.out.println("main().Days.MONDAY.equals(day) : " + Days.MONDAY.equals(day)); // Why is this false when below is OK.
System.out.println("main().Days.MONDAY.toString().equals(day) : " + Days.MONDAY.toString().equals(day));// This is true
System.out.println("main().Days.MONDAY.name().equals(day) : " + Days.MONDAY.name().equals(day)); // This is true and I know this is the correct way

编辑:这是枚举。

enum Days{
    MONDAY,TUESDAY,WEDENSDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}

【问题讨论】:

  • 您正在将字符串与枚举进行比较——它们不能相等...
  • System.out.println("main().Days.MONDAY : " + Days.MONDAY); 上隐式调用Days.MONDAY.toString() 方法。

标签: java enums equals tostring


【解决方案1】:

Enum 的 equals 方法比较 Enum 的静态实例。因为枚举的任何表示都指向同一个对象实例。 所以 Enum 的 equals 方法不是比较 Name 或 toString 而是比较实例。

【讨论】:

    【解决方案2】:
    String day="MONDAY";
    

    以上行在 Constant Pool 内创建Object,其中

    public enum Days{
    MONDAY  <-- Created in HEAP
    }
    

    现在来了

    Days.MONDAY.equals(day) --> Why False ?
    

    equals() 的 Enum 方法比较 Enum 的实例而不是 data 的实例,就像 String#equals() 所做的那样!!

    Days.MONDAY.toString().equals(day) --> Why true ?
    

    因为是String#equals() 方法被重载了!!

    【讨论】:

      【解决方案3】:

      看看is-it-ok-to-use-on-enums-in-java。基于此,Java 在 Enum 上的 equals 实现简单地执行了 ==。由于您示例中的 Enum 和 String day 不是同一个对象,因此它返回 false。

      【讨论】:

        【解决方案4】:

        Object 类的方法具有严格定义的契约。

        其中一种方法是 Object.equals() 方法 - 这里是 its documentation

        为了能够保持对称性要求,实际上不可能在equals() 的任何实现中返回true,除非被比较的两个对象属于同一类。 equals() 应该表示它们的属性之间的某种等价物,但不属于同一类的对象不具有相同的属性。

        不要将Days 对象Days.MONDAYDays.MONDAY.toString() 返回的字符串混淆。它的toString()只是返回一个代表它的字符串,两个字符串是可以相等的对象。但是Days.MONDAY.toString() 不是对象本身(试试Days.MONDAY.equals( Day.MONDAY.toString() ),你也会在这里得到错误!

        当您将对象发送到System.out 或任何其他PrintWriterprint()println() 方法时,print() 将获取该对象的toString() 值并打印它。这就是他们“打印相同的东西”的原因。实际上,正在打印的不是 MONDAY 对象(很难定义“打印对象”),而是从其 toString() 方法返回的字符串 "MONDAY"

        即使Days 不是一个枚举而是其他一些不是字符串的对象,所有这些都将成立,尽管在枚举的特定情况下,它的equals() 方法确实是比较引用而不是属性.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-08-14
          • 1970-01-01
          • 2011-10-29
          • 2020-04-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-07
          相关资源
          最近更新 更多