为什么我会使用Enum,而不只是一个类?

时间:2012-08-14 13:50:11

标签: java enums

前几天我用Java帮助了一个朋友,他们问的是Enums。我解释了(类似的)

的C语法
enumeration Difficulty{
    BEGINNER= 1;
    PRO=5;
    EXPERT = 11;
}

不是要走的路,Java语法是something(1);你做了一个接受int的构造函数然后做了这个......等等。

但是他们阻止了我,并问“如果我们使用构造函数等等,为什么还要使用枚举,为什么不只是有一个新类?”

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

7 个答案:

答案 0 :(得分:9)

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

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

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

答案 1 :(得分:6)

enum具有平原类所没有的许多功能。

  • 他们在一个地方定义了固定数量的实例。
  • 它们可用于switch语句。
  • 获取完整的枚举列表
  • 从字符串中查找枚举。
  • 可以获得枚举的名称。
  • 可以对单个枚举值进行子类化。

答案 2 :(得分: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版本强大得多。当然,通过枚举,可以保证枚举的每个成员都是单身。

答案 3 :(得分:4)

以下是使用枚举的原因 -

1)枚举是类型安全的,你不能将除预定义枚举常量之外的任何东西分配给枚举变量。

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

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

4)在Java中使用Enum添加新常量非常简单,您可以在不破坏现有代码的情况下添加新常量。

答案 4 :(得分:1)

Enum还在Java中创造了一个伟大的单身人士:

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

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

答案 5 :(得分:0)

如果您有一组修正值,则使用枚举,枚举在...... ehhm ...枚举:)

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

答案 6 :(得分:0)

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