枚举等于()和==

时间:2014-07-02 02:21:48

标签: java enums

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。任何人都可以解释这种行为为什么是真的?

5 个答案:

答案 0 :(得分:5)

==应该可以正常使用枚举,因为没有给定枚举项的多个引用;只有一个。 Java Language Specification section on enum types, 8.9表示它们隐式静态且最终,因此只能创建一次。

答案 1 :(得分: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

每次valueOf String的{​​{1}}调用。

答案 2 :(得分:1)

Enum Types来自文档,

  

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

     

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

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

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

valueOf方法仅作为 Flyweight :JVM保留某种字典并返回相应的枚举项实例。

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