Java中的枚举类初始化
在Java中,我们可以执行以下操作来初始化该类中的类和调用方法:
public class MyClass { public String myClassMethod() { return "MyClass"; } }
。
public class Test { public static void main(String[] args) { MyClass myClass = new MyClass(); // initialize MyClass myClass.myClassMethod();// call a method } }
如果我的类是enum
类,则实现如下:
public enum MyEnumClass { INSTANCE; public String myEnumClassMethod() { return "MyEnumClass"; } }
。
public class Test { public static void main(String[] args) { MyEnumClass myEnumClass = MyEnumClass.INSTANCE; myEnumClass.myEnumClassMethod(); } }
这两种情况都以相同的方式工作,但据说它在enum
实现中更好。 我的问题是为什么以及如何发生?
enum
本质上是单例模式。
JVM处理enum
实例的初始化和存储。 要最清楚地看到这一点,你可以写:
public enum MyEnumClass { INSTANCE("some value for the string."); private final String someString; private MyEnumClass(final String someString) { this.someString = someString; } public String getSomeString(){ return someString; } }
在另一个class级:
public static void main(String[] args) { final MyEnumClass myEnumClass = MyEnumClass.INSTANCE; system.out.println(myEnumClass.getSomeString()); }
这将打印出“字符串的某些值”。
这表明enum
实例在类加载时初始化,即好像是由static
初始化器初始化的。
或者换一种方式,如果你不在MyClass
覆盖equals
那么
new MyClass() == new MyClass();
永远是false
,而:
MyEnumClass.INSTANCE == MyEnumClass.INSTANCE;
永远是true
。 即MyEnumClass.INSTANCE
始终是相同的 MyEnumClass.INSTANCE
而每次调用new MyClass()
时都会创建一个new MyClass()
。
这给我们带来了很好的“更好”的问题。
enum
是一个单例实例,具有各种漂亮的方法,用于将String
enum
名称转换为对它所代表的单例实例的引用。 它还保证,如果您对enum
反序列化,则不会有像普通类那样的两个单独的实例。
因此,作为一个强大的线程安全单例而不是class
, enum
肯定要好得多。
但是我们不能有两个INSTANCE
和someString
的不同值,所以enum
作为一个class
是没用的……
简而言之, enum
s对于他们有益的东西是有益的,而且对于他们有益的东西而言,它们是有益的。 它们不是替代品,因此当一个用作另一个时,不能以任何有意义的方式进行比较。
它是Singleton模式的简单实现,依赖于Enum工作的机制。
如果您MyEnumClass.INSTANCE
使用MyEnumClass.INSTANCE
,您将获得相同的对象实例。
相比之下, new MyClass();
将创建一个新对象。
另见这里的讨论:
在Java中使用Enum作为单例的最佳方法是什么?
阅读Java语言规范第8-9节可能还有更多需要学习的内容