Java枚举和具有私有构造函数的类之间有什么区别?

2022-08-31 15:41:59

我试图理解Java枚举是如何工作的,我得出的结论是,它与普通的Java类非常相似,它的构造函数声明为私有。

我刚刚得出了这个结论,它不是基于太多的思考,但Id想知道我是否错过了什么。

下面是一个简单的 Java 枚举和一个等效的 Java 类的实现。

public enum Direction {
    ENUM_UP(0, -1),
    ENUM_DOWN(0, 1),
    ENUM_RIGHT(1, 0),
    ENUM_LEFT(-1, 0);


    private int x;
    private int y;

    private Direction(int x, int y){
        this.x = x;
        this.y = y;
    }
    public int getEnumX(){
        return x;
    }
    public int getEnumY(){
        return y;
    }
}

上面和下面的代码在含义上有什么区别?

public class Direction{
    public static final Direction UP = new Direction(0, -1) ;
    public static final Direction DOWN = new Direction(0, 1) ;
    public static final Direction LEFT = new Direction(-1, 0) ;
    public static final Direction RIGHT = new Direction(1, 0) ;


    private int x ;
    private int y ;

    private Direction(int x, int y){
        this.x = x ;
        this.y = y ;
    }
    public int getX(){
        return x;
    }
    public int getY(){
        return y;
    }
}

答案 1

差异:

  1. 枚举扩展并获得其所有不错的功能java.lang.Enum
    1. 通过正确的序列化实现自动单例行为
    2. 枚举值上的自动人类可读方法,无需复制枚举名称.toString
    3. .name和特殊用途方法.ordinal
    4. 可用于基于位集的高性能和类EnumSetEnumMap
  2. 枚举由语言特殊处理:
    1. 枚举使用特殊语法,无需写入数十个字段即可简化实例创建public static final
    2. 枚举可用于语句switch
    3. 枚举不能在枚举列表之外实例化,除非使用反射
    4. 枚举不能扩展到枚举列表之外
  3. Java会自动将额外的内容编译为枚举:
    1. public static (Enum)[] values();
    2. public static (Enum) valueOf(java.lang.String);
    3. private static final (Enum)[] $VALUES; (values()返回此的克隆)

其中大多数都可以使用设计合理的类进行模拟,但只是使创建具有这组特别理想的属性的类变得非常容易。Enum


答案 2

回答这个问题:从本质上讲,这两种方法之间没有区别。但是,枚举构造为您提供了一些额外的支持方法,例如 ,等,您必须使用类与私有构造函数方法自行编写。values()valueOf()

但是,是的,我喜欢Java枚举的方式,就像Java中的任何其他类一样,它们可以具有字段,行为等。但对我来说,枚举与普通类的区别在于枚举是实例/成员是预先确定的类/类型。与通常的类(您可以从中创建任意数量的实例)不同,枚举仅将创建限制为已知实例。是的,正如您所说明的,您也可以使用具有私有构造函数的类执行此操作,但枚举只会使此操作更加直观。