枚举和最终变量有什么区别?

时间:2013-12-18 15:25:36

标签: java enums

我正在尝试阅读枚举以更好地理解它们。

从枚举的javadocs我得到以下内容:

  

枚举类型是一种特殊数据类型,它使变量成为一组预定义常量。

对我而言,这听起来很像final变量。

  1. 真正的区别是什么?
  2. 你什么时候用一个而不是另一个?
  3. 枚举只是一个最终变量,可以是一组东西吗?

6 个答案:

答案 0 :(得分:5)

不同之处在于枚举提供类型安全

我们有enum

public enum MuEnum {
    FIRST("First"), SECOND("Second");

    private String value;

    MyEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

考虑以下示例:

public void myMethod(MyEnum parameter) { .. }

此处,您只能传递MyEnum个值(FIRSTSECOND),而您的方法签名是:

public void myMethod(String parameter) { .. }

您可以传递无效参数(某些String,其内容与"First""Second"不同。

答案 1 :(得分:3)

当您有enum之类的

public enum MyEnum {
   FIRST_COSTANT, SECOND_CONSTANT;
}

你实际拥有的是

public class /* enum */ MyEnum extends Enum<MyEnum> {
    private Enum() {}
    public final static MyEnum FIRST_CONSTANT = new MyEnum() {};
    public final static MyEnum SECOND_CONSTANT = new MyEnum() {};    
    ... // methods     
}

所以在这个意义上,是的,它们是一样的。

Java语言规范here中对此进行了解释。

  

除了Enum类型E继承自Enum的成员之外,   对于每个声明的枚举常量,名称为n,枚举类型为   隐式声明名为n的类型为E的公共静态最终字段。这些   字段被认为是以与。相同的顺序声明   相应的枚举常量,在任何静态字段之前显式   在枚举类型中声明。每个这样的字段都初始化为枚举   与之对应的常数。每个这样的领域也被认为是   用与相应枚举相同的注释注释   不变。枚举常量据说是在创建时创建的   相应的字段已初始化。

答案 2 :(得分:3)

有一个很大的区别:首先,enum,不是变量,它是一种类型。 final变量,例如int,可以在int的许多可能值中包含一个预设值,而enum变量(也可以是final变量{1}})可以包含您在定义enum时声明的集合中的值。

以下是一个例子:

enum Color {Red, Green, Blue;}

上面的声明没有定义变量。它定义了Color 类型的变量可以具有的一组值,如果您选择声明一个:

Color backgroundColor = Color.Red;

现在您有一个枚举类型Color的非final变量。它的值可以改变,但它必须是作为enum的一部分定义的三个值之一。

实际上,当您使用固定数量的状态建模时,可以使用enum,您希望为其命名。您也可以使用一个或多个final变量,实际上,在引入enum之前已经做了很多。例如,Java的Calendar类使用static final int常量来表示日期的各个部分,其中enum可以更好地工作。

答案 3 :(得分:2)

我认为枚举不是最终的,因为你可以为枚举描述符中的每个字段定义一个匿名子类。

来自文档:

  

枚举类型(第8.9节)不得声明为抽象;这样做会导致   在编译时错误。

     

枚举类型是隐式最终的,除非它包含至少一个枚举   具有类体的常数。

     

显式声明枚举类型是编译时错误   最终

     

嵌套枚举类型是隐式静态的。允许   显式声明嵌套的枚举类型是静态的。

还要标记一个观点,即如果我们将一个类称为Final,则意味着它们不能被继承。但是,当涉及到枚举时,默认情况下它们不能被继承。

答案 4 :(得分:1)

以一种思维方式,是的。以下陈述大致相同:

// This...
final int FIRST = 0;
final int SECOND = 1;

// Is roughly equivalent to this.
enum Ordering = { FIRST, SECOND };

区别在于类型安全。由于Ordering枚举命名为新类型,因此您可以使用Ordering而不是int的函数。这样可以确保在编译时不会意外地将超出范围的值(如2)传递给期望Ordering的函数。

void foo(Ordering order) {;}

foo(FIRST); // This works
foo(3); // This causes an error at compile time

答案 5 :(得分:0)

枚举用于您知道您将拥有多少个类型实例的每种情况。是的,在枚举之前,使用了静态最终变量。

Enums提供了一些简单的静态最终变量没有的细节:

  • 他们是打字的。
  • 他们提供了一些有用的方法,比如valueOf,它允许通过名字查找它们,或者枚举它们。
  • 每个实例都可以覆盖枚举的方法以提供特定的行为。
  • Enum确保不会有任何其他类的实例,而不必将构造函数设置为私有或其他可以通过反射克服的技巧。因此,实现像Singleton模式这样的模式是一种很好的方法。