为什么两个枚举常量可以在同一行中使用?



我创建了一个枚举类:

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枚举的条目:

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!

但是使用如此糟糕的技术和大量的缺点绝对没有任何好处。