Я постараюсь добавить немного больше к тому, что было сказано в комментариях выше.
Значения перечисления несколько особенные.Из записи Wikipedia по перечислениям Java:
Тип перечисления в Java на самом деле представляет собой специальный класс, сгенерированный компилятором, а не арифметический тип, а значения перечисления ведут себя как глобальныесгенерированные экземпляры этого класса.Типы enum могут иметь методы экземпляра и конструктор (аргументы которого можно указывать отдельно для каждого значения enum).
Таким образом, в то время как они генерируются только один раз во время компиляции, они являются специальными экземплярами заданного типа перечисления.Как таковой, он имеет доступ к другим членам класса.Обратите внимание, что это также подразумевает, что вы не можете создать экземпляр типа enum самостоятельно (то есть, используя new
).
Из одного экземпляра класса enum вы можете получить доступ к другому экземпляру того же класса enum?Что я не видел в обычном классе 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!
Но выиграть от этой выгоды абсолютно нет.используя такую ужасную технику и массу недостатков.