5

前几天我在帮助一个朋友使用 Java,他们在询问 Enums。我解释了(类似的)的C语法

enumeration Difficulty{
    BEGINNER= 1;
    PRO=5;
    EXPERT = 11;
}

不是要走的路,Java 语法是something(1);您创建了一个接受 int 的构造函数,然后执行此操作...等等。

但他们拦住了我,问我“如果我们使用构造函数等等,为什么要使用枚举,为什么不直接创建一个新类?”

而我无法回答。那么在这种情况下为什么要使用枚举而不是类呢?

4

7 回答 7

10

枚举受到严格限制。在指定值之外定义枚举值是不可能的(而您可以调用一个类new来创建一个新值)。

至少大多数 JVM 也对枚举进行了大量优化,并且还有新的类和语言特性可以利用枚举的紧凑性和速度。例如,创建了新类EnumSetEnumMap,它们分别使用位集和数组实现了一个枚举键集或映射(这可能是那些抽象数据类型的最快实现)。

此外,枚举类型可以在switch语句中使用。如果您是 Java1.7 之前的版本,这是自定义switch语句的最佳选择(并且由于类型安全性可能仍然优于使用String值;错误输入枚举值会导致编译时错误,但错误输入字符串会导致一个更隐蔽的运行时错误——或者更糟糕的是,一个在你真正盯着代码并看到错字之前你无法理解的逻辑错误)。

于 2012-08-14T13:53:07.033 回答
6

枚举有许多普通类没有的特性。

  • 它们具有固定数量的实例,您可以在一个位置定义这些实例。
  • 它们可以在 switch 语句中使用。
  • 获取完整的枚举列表
  • 从它的字符串中查找一个枚举。
  • 可以获得枚举的名称。
  • 可以对单个枚举值进行子类化。
于 2012-08-14T13:54:26.050 回答
6

好吧,实际上 Java 中的 Enum 只是用于声明整个类层次结构的语法糖。

写作:

public enum MyEnum {
   FOO, BAR
}

大致相当于写

public abstract class MyEnum {
    public static final MyEnum FOO = new MyEnum(){};
    public static final MyEnum BAR = new MyEnum(){};

    private MyEnum(){}
}

乍一看,这似乎有点矫枉过正,但您意识到您可以做所有类可以做的事情,例如:

public enum Operators {
    ADD("+"){ 
        public double apply(double lhs, double rhs){ return lhs + rhs; }
    },

    SUBTRACT("-"){ 
        public double apply(double lhs, double rhs){ return lhs - rhs; }
    },

    MULTIPLY("*"){ 
        public double apply(double lhs, double rhs){ return lhs * rhs; }
    },

    DIVIDE("/"){ 
        public double apply(double lhs, double rhs){ return lhs / rhs; }
    };

    private final String symbol;

    Operators(String symbol){
        this.symbol = symbol;
    }

    public abstract double apply(double lhs, double rhs);
}

现在相当于(加上一些额外的便利方法):

public abstract class Operators {
    public static final Operators ADD = new Operators("+"){ 
        public double apply(double lhs, double rhs){ return lhs + rhs; }
    };

    public static final Operators SUBTRACT = new Operators("-"){ 
        public double apply(double lhs, double rhs){ return lhs - rhs; }
    };

    public static final Operators MULTIPLY = new Operators("*"){ 
        public double apply(double lhs, double rhs){ return lhs * rhs; }
    },

    public static final Operators DIVIDE = new Operators("/"){ 
        public double apply(double lhs, double rhs){ return lhs / rhs; }
    };

    private final String symbol;

    private Operators(String symbol){
        this.symbol = symbol;
    }

    public abstract double apply(double lhs, double rhs);
}

我相信我们可以同意它比非常基本的 C 版本更强大。当然,使用枚举可以保证枚举的每个成员都是单例。

于 2012-08-14T14:02:29.810 回答
4

以下是使用枚举的原因 -

1)枚举是类型安全的,除了预定义的枚举常量之外,您不能将任何其他内容分配给枚举变量。

2) Enum 有自己的命名空间。

3) Enum 的最大特点是您可以在 Java 中的 Switch 语句中使用 Enum,如 int 或 char 原始数据类型。但是在 java 7 中,我们可以在 switch 语句中使用 String。

4) 在 Java 中的 Enum 上添加新常量很容易,您可以在不破坏现有代码的情况下添加新常量。

于 2012-08-14T13:53:16.163 回答
1

Enum 还为 Java 提供了一个很棒的单例:

http://en.wikipedia.org/wiki/Singleton_pattern#The_Enum_way

我想这是您可以使用枚举而不是类的另一种情况。

于 2012-08-20T16:08:06.423 回答
0

如果您有一组固定的值,则使用枚举,枚举在 ... ehhm ... enum :)

如果您想要类描述的任何数量的实例,您可以使用类。

于 2012-08-14T13:52:34.617 回答
0

因为一个类可以有任意数量的实例,而在“枚举”中,实例的数量仅限于枚举本身的元素(这就是为什么构造函数必须是私有的),并且可以静态访问这些实例。

于 2012-08-14T13:53:41.137 回答