我创建了一个Enum类:
public enum Currency {
PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
private int value;
private Currency(int value) {
this.value = value;
}
};
我试图在main()方法中使用它:
System.out.println(Currency.NICKLE.DIME.PENNY.QUARTER);
System.out.println(Currency.PENNY.QUARTER);
此处没有生成错误。它打印最后的常量。
有人可以解释一下吗?
答案 0 :(得分:2)
我会尝试对上述评论中的内容进行更多补充。
枚举值有些特殊。来自Java枚举的Wikipedia条目:
Java中的枚举类型实际上是一个特殊的编译器生成的类而不是算术类型,枚举值表现为该类的全局预生成实例。枚举类型可以有实例方法和构造函数(可以为每个枚举值单独指定其参数)。
因此,虽然它们仅在编译时生成一次,但它们是给定枚举类型的特殊实例。因此,它可以访问该类的其他成员。请注意,这也意味着您无法自己实例化枚举类型(即使用new
)。
从枚举类的一个实例中,您可以访问同一枚举类的另一个实例?我在普通的Java课程中看不到。
这在普通班级中也是可能的,虽然不赞成,因为它没有提供任何实际好处,甚至可能导致问题和错误(通过NullPointerException
)。
考虑以下两个类:
public class SomeClass
{
public final static int MODE = 1;
private String message;
public SomeClass(String message)
{
this.message = message;
}
}
public class Test
{
public static void main(String[] args)
{
SomeClass myObject = new SomeClass("bla");
System.out.println(myObject.MODE);
System.out.println(OtherClass.MODE);
}
}
这只是打印出来:
1
1
但是,假设您正在执行某些任务,其中您遍历SomeClass
个对象列表,其中某些条目可能是null
(可能是因为它们在某些时候被从集合中删除,或者因为任何原因在插入时允许null
条目。)
在这种情况下,如果您通过实例访问static
成员,您将获得NPE,而通过类本身访问它将按预期工作。
请注意,问题中描述的行为特定于enum
类型本身(即Currency.NICKLE.DIME...
)。有一种模仿行为的方法,如下所示:
public class SomeClass
{
public static SomeClass REF; // not final anymore since 'this' must be the first line in a constructor call
public String message; // note this is public now
public SomeClass(String message)
{
this.message = message;
}
public void setRef() {
REF = this;
}
}
public class Test
{
public static void main(String[] args)
{
SomeClass myObject = new SomeClass("bla!");
System.out.println(myObject.REF);
System.out.println(SomeClass.REF);
myObject.setRef();
System.out.println(SomeClass.REF);
System.out.println(SomeClass.REF.message);
}
}
这将打印出来:
null
null
SomeClass@... // Object.toString() call
bla!
但使用这种糟糕的技术和许多缺点绝对没有任何好处。