1

在 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执行起来更好。我的问题是为什么以及如何发生?

4

2 回答 2

8

Anenum本质上是一个单例模式。

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;
    }
}

在另一个班级:

public static void main(String[] args) {
    final MyEnumClass myEnumClass = MyEnumClass.INSTANCE;
    system.out.println(myEnumClass.getSomeString());
}

这将打印出“字符串的一些值。”。

这表明enum实例是在类加载时初始化的,即好像是由static初始化程序初始化的。

或者换一种说法:

new MyClass() == new MyClass();

总是false而:

MyEnumClass.INSTANCE == MyEnumClass.INSTANCE;

总是true。_ ieMyEnumClass.INSTANCE总是相同 MyEnumClass.INSTANCE的,而每次调用时都会创建一个新MyClassnew MyClass()的。

这使我们很好地回答了您“更好”的问题。

Anenum是一个单例实例,具有各种漂亮的方法,用于将String enum名称转换为对它所代表的单例实例的引用。它还保证如果您反序列化 anenum将不会像普通类那样有两个单独的实例。

因此,enum作为健壮且线程安全的单例, an 肯定比 a 好得多class

但是我们不能有两个INSTANCE具有不同值的实例someString所以enum作为...class

简而言之enum,s 适合他们擅长的事情,classes 适合他们擅长的事情。它们不是替代品,因此无法以任何有意义的方式进行比较,除非将其中一个用作另一个。

于 2013-11-14T07:38:50.343 回答
1

它是单例模式的简单实现,依赖于 Enum 的工作机制。

如果您MyEnumClass.INSTANCE第二次使用,您将获得相同的对象实例。

相反,new MyClass();会创建一个新对象。

另请参阅此处的讨论:

在 Java 中使用枚举作为单例的最佳方法是什么?

通过阅读Java 语言规范第 8-9 节可能会学到更多

于 2013-11-14T07:38:26.800 回答