我创建了一个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);
这没有产生错误。它打印最后的常量。
有人可以解释一下吗?
我将尝试在上述评论中添加更多内容。
枚举值有些特殊。来自Java枚举的Wikipedia条目:
Java中的枚举类型实际上是一个特殊的编译器生成的类而不是算术类型,枚举值表现为该类的全局预生成实例。枚举类型可以包含实例方法和构造函数(可以为每个枚举值单独指定其参数)。
因此,虽然它们仅在编译时生成一次,但它们是给定枚举类型的特殊实例。因此,它可以访问该类的其他成员。请注意,这也意味着您无法自己实例化枚举类型(即使用new
)。
从枚举类的一个实例,您可以访问相同枚举类的另一个实例?我在普通的Java类中没有看到过。
这在普通班级也是可能的,虽然不赞成,因为它没有提供真正的好处,甚至可能导致问题和错误(通过NullPointerException
s)。
考虑以下两个类:
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!
但是使用这种糟糕的技术和许多缺点绝对没有任何好处。