Enum equals() and ==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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应为假。有人能解释这种行为为什么是真的吗?
您正在比较枚举常量。这意味着对于每个枚举常量,都会创建一个实例。
这个
1 2 3 4 | enum Drill{ ATTENTION("Attention!"), AT_EASE("At Ease"); ... } |
或多或少等同于
1 2 3 4 5 | final class Drill { public static final Drill ATTENTION = new Drill("Attention!") {}; public static final Drill AT_EASE = new Drill("At Ease") {}; ... } |
1 2 3 4 5 6 7 8 9 10 11 12 | /** * 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); |
返回变量引用的实例值,该变量的名称等于指定的
所以
1 | Drill.valueOf("ATTENTION") == Drill.ATTENTION |
每次调用
文件中的
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.
Because they are constants, the names of an enum type's fields are in uppercase letters.
1 2 | Drill d1= Drill.valueOf("ATTENTION"); // ATTENTION Drill d2= Drill.valueOf("ATTENTION"); // ATTENTION |
因此,
在枚举中,所有项都是单例的:它们只构造一次(为了在执行开始时简单化,主要是在需要时)。因此,它们遵循单例模式(可能是使用单例模式的唯一好理由之一)。
因此,在内存中,
另一方面,我认为使用
JVM的组织方式使得不可能或实际上不可能实例化每个枚举常量的多个实例。http://docs.oracle.com/javase/tutorial/java/javaoo/enum.html
当调用valueof时,它只返回已经实例化的枚举常量。