【问题标题】:Enum equals() and == [duplicate]枚举 equals() 和 == [重复]
【发布时间】:2014-08-22 16:50:41
【问题描述】:
enum Drill{
        ATTENTION("Attention!"), AT_EASE("At Ease");    
        private String str; 
        private Drill(String str){
            this.str = str;
        }
        public String toString(){
            return str;
        }
    }
public class EnumExample {
    public static void main(String[] args) {
            Drill d1= Drill.valueOf("ATTENTION");
            Drill d2= Drill.valueOf("ATTENTION");
            **System.out.println(d1.equals(d2));//TRUE
            System.out.println(d1==d2);//TRUE**
            System.out.println(Drill.ATTENTION.equals(Drill.valueOf("ATTENTION")));
            System.out.println(Drill.ATTENTION.equals(Drill.AT_EASE));//FALSE 
            System.out.println(Drill.ATTENTION==Drill.valueOf("ATTENTION"));//TRUE
            System.out.println(Drill.ATTENTION==Drill.AT_EASE);//FALSE
}
}

使用 == 和 equals() 时的枚举行为似乎相同。据我所知,== 只是检查参考。因此 d1 == d2 应该是 FALSE。谁能解释这种行为为什么是真的?

【问题讨论】:

    标签: java enums


    【解决方案1】:

    == 应该可以很好地处理枚举,因为给定的枚举项没有多个引用;只有一个。 Java Language Specification section on enum types, 8.9 声明它们是隐式的静态和最终,因此只能创建一次。

    【讨论】:

    • 谢谢。你的意思是说,所有对同一个枚举常量的引用都是一样的?
    • @user3781572 他们指的是同一个对象。
    • @user3781572:它们是隐式最终的,只能创建一次。
    【解决方案2】:

    您正在比较枚举常量。这意味着对于每个枚举常量,都会创建一个实例。

    这个

    enum Drill{
        ATTENTION("Attention!"), AT_EASE("At Ease"); 
        ...
    }
    

    或多或少等同于

    final class Drill {
        public static final Drill ATTENTION = new Drill("Attention!") {};
        public static final Drill AT_EASE = new Drill("At Ease") {};
        ...
    }
    

    valueOf method

    /**
    * Returns the enum constant of this type with the specified
    * name.
    * The string must match exactly an identifier used to declare
    * an enum constant in this type.  (Extraneous whitespace 
    * characters are not permitted.)
    * 
    * @return the enum constant with the specified name
    * @throws IllegalArgumentException if this enum type has no
    * constant with the specified name
    */
    public static E valueOf(String name);
    

    返回名称等于指定String 值的变量引用的实例的值。

    所以

    Drill.valueOf("ATTENTION") == Drill.ATTENTION
    

    对于具有 String 值的 valueOf 的每次调用。

    【讨论】:

    • 您可能需要将new ATTENTION 替换为new Drill
    • @CommuSoft 哈哈,是的。谢谢。
    【解决方案3】:

    Enum Types 来自文档,

    枚举类型是一种特殊的数据类型,它使变量成为一组预定义的常量。该变量必须等于为其预定义的值之一。常见示例包括罗盘方向(NORTH、SOUTH、EAST 和 WEST 的值)和星期几。

    因为它们是常量,所以枚举类型的字段名都是大写的。

    Drill d1= Drill.valueOf("ATTENTION"); // ATTENTION
    Drill d2= Drill.valueOf("ATTENTION"); // ATTENTION
    

    所以d1 == d2d1.equals(d2) 因为它们引用相同的常量值,即Drill.ATTENTION

    【讨论】:

    • 编辑为 i.e. v. e.g.它经常对技术文档产生很大影响,所以我认为我应该更正。
    【解决方案4】:

    JVM 的组织方式是不可能或实际上不可能实例化每个枚举常量的多个实例。 http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

    当你调用 valueOf 时,它只是返回已经实例化的枚举常量。

    【讨论】:

      【解决方案5】:

      在一个枚举中,所有项目都是单例:它们被构造一次(为了在执行开始时简单起见,主要是在需要时)。因此它们遵循单例模式(可能是使用单例的唯一充分理由之一)。

      因此在内存中,enum 中的每个元素都有一个实例。

      valueOf 方法仅充当享元:JVM 保留某种字典并返回适当的枚举项实例。

      在旁注中,我认为仍然建议使用equals 方法,因为这为程序员提供了在枚举项上定义相等分区的机会。 (比如说AB 是相等的,但是有一些不同的行为)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-02
        • 2012-08-31
        • 2016-03-05
        • 2013-11-06
        • 2010-12-17
        • 2011-04-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多