Java 枚举和最终变量有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20662018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's difference between enums and final variables?
提问by Marc Rasmussen
I am trying to read up on enums to better understand them.
我正在尝试阅读枚举以更好地理解它们。
From the javadocs of enums I get the following:
从枚举的 javadocs 我得到以下信息:
An enum type is a special data type that enables for a variable to be a set of predefined constants.
枚举类型是一种特殊的数据类型,它使变量成为一组预定义的常量。
To me this sounds a lot like a final
variable.
对我来说,这听起来很像一个final
变量。
- What is the real difference?
- And when would you use one over the other?
- Is enum just a final variable that can be a set of things?
- 真正的区别是什么?
- 你什么时候会使用一个?
- 枚举只是一个可以是一组事物的最终变量吗?
采纳答案by Sotirios Delimanolis
When you have an enum
like
当你有一个enum
赞
public enum MyEnum {
FIRST_COSTANT, SECOND_CONSTANT;
}
What you actually have is
你真正拥有的是
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
}
So in that sense, yes, they are the same.
所以从这个意义上说,是的,它们是一样的。
This is explained in the Java Language Specification here.
这在此处的 Java 语言规范中进行了解释。
In addition to the members that an enum type E inherits from Enum, for each declared enum constant with the name n, the enum type has an implicitly declared public static final field named n of type E. These fields are considered to be declared in the same order as the corresponding enum constants, before any static fields explicitly declared in the enum type. Each such field is initialized to the enum constant that corresponds to it. Each such field is also considered to be annotated by the same annotations as the corresponding enum constant. The enum constant is said to be created when the corresponding field is initialized.
除了枚举类型 E 从 Enum 继承的成员之外, 对于每个名为 n 的声明的枚举常量,枚举类型都有一个隐式声明的名为 n 的类型 E 的公共静态最终字段。在枚举类型中显式声明的任何静态字段之前,这些字段被视为以与相应枚举常量相同的顺序声明。每个这样的字段都被初始化为与之对应的枚举常量。每个这样的字段也被认为是由与相应的枚举常量相同的注释进行注释的。枚举常量是在初始化相应字段时创建的。
回答by Rahul Tripathi
I think enums are not final because you can define an anonymous subclass for each field inside of the enum descriptor.
我认为枚举不是最终的,因为您可以为枚举描述符内的每个字段定义一个匿名子类。
From the docs:
从文档:
Enum types (§8.9) must not be declared abstract; doing so will result in a compile-time error.
An enum type is implicitly final unless it contains at least one enum constant that has a class body.
It is a compile-time error to explicitly declare an enum type to be final.
Nested enum types are implicitly static. It is permissible to explicitly declare a nested enum type to be static.
枚举类型(第 8.9 节)不得声明为抽象类型;这样做会导致编译时错误。
枚举类型是隐式 final 的,除非它至少包含一个具有类主体的枚举常量。
将枚举类型显式声明为 final 是编译时错误。
嵌套的枚举类型是隐式静态的。允许将嵌套枚举类型显式声明为静态。
Also to mark a point that if we say a class as Final then it means that they can not be inherited. However, when it comes to enums then they can not be inherited by default.
还要指出一点,如果我们说一个类为 Final 那么这意味着它们不能被继承。但是,当涉及到枚举时,默认情况下它们不能被继承。
回答by Konstantin Yovkov
The difference is that enums provide type safety.
不同之处在于枚举提供类型安全。
Let's have this enum
.
让我们有这个enum
。
public enum MuEnum {
FIRST("First"), SECOND("Second");
private String value;
MyEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
Consider the following example:
考虑以下示例:
public void myMethod(MyEnum parameter) { .. }
Here, you can only pass MyEnum
values (FIRST
or SECOND
), while if your method signature was:
在这里,您只能传递MyEnum
值(FIRST
或SECOND
),而如果您的方法签名是:
public void myMethod(String parameter) { .. }
you would be able to pass an invalid parameter (some String
which content is different than "First"
or "Second"
).
您将能够传递无效参数(某些String
内容与"First"
或不同"Second"
)。
回答by dasblinkenlight
There is a big difference: first, enum
, is not a variable, it is a type. A final
variable, say, an int
, can have a single, preset value from among many possible values of int
, while an enum
variable (which could also be final
) can have a value from a set that you declare when defining the enum
.
有一个很大的区别:首先,enum
, 不是一个变量,它是一个类型。一个final
变量,比如 an int
,可以有一个来自 的许多可能值中的单个预设值int
,而一个enum
变量(也可以是final
)可以有一个你在定义 时声明的集合中的值enum
。
Here is an example:
下面是一个例子:
enum Color {Red, Green, Blue;}
The declaration above does not define a variable. It defines a set of values a variable of type Color
couldhave, if you choose to declare one:
上面的声明没有定义变量。它定义了一组类型的变量Color
可能具有的值,如果您选择声明一个:
Color backgroundColor = Color.Red;
Now you have a non-final variable of an enumerated type Color
. Its value can change, but it must be one of the three values defined as part of the enum
.
现在您有一个枚举类型的非最终变量Color
。它的值可以改变,但它必须是定义为enum
.
In practice, you use an enum
when you model a something with a fixed number of states, to which you would like to give a name. You could use one or more final
variables for that, too, - in fact, this has been done a lot before enum
s were introduced. For example, Java's Calendar
class uses static final int
constants for the various parts of the date, where an enum
would have worked better.
在实践中,enum
当您对具有固定数量状态的事物进行建模时,您会使用 an ,您希望为其命名。您也可以final
为此使用一个或多个变量 - 事实上,enum
在引入 s之前已经这样做了很多。例如,Java 的Calendar
类static final int
对日期的各个部分使用常量,在这些部分使用anenum
会更好。
回答by Elliot Robinson
In one way of thinking, yes. The following statements are roughly equivalent:
在一种思维方式中,是的。以下语句大致等效:
// This...
final int FIRST = 0;
final int SECOND = 1;
// Is roughly equivalent to this.
enum Ordering = { FIRST, SECOND };
The difference is type safety. Since the Ordering
enum names a new type, you can have a function which takes an Ordering
rather than an int
. This ensures at compile time that you don't accidentally pass an out of bounds value (like 2) to a function expecting an Ordering
.
区别在于类型安全。由于Ordering
枚举命名了一种新类型,因此您可以拥有一个采用 anOrdering
而不是 的函数int
。这可确保在编译时不会意外地将越界值(如 2)传递给需要Ordering
.
void foo(Ordering order) {;}
foo(FIRST); // This works
foo(3); // This causes an error at compile time
回答by Cyrille Ka
Enums are used for every case where you know how many instances of a type you will have. Yes, before enums, static final variables were used.
枚举用于您知道将拥有多少类型实例的每种情况。是的,在枚举之前,使用了静态最终变量。
Enums provides a few niceties that simple static final variables do not have:
枚举提供了一些简单的静态最终变量所没有的优点:
- They are typed.
- They come with some helpful methods like valueOf, that allows to look for them by their name, or to enumerate them.
- Each instance can override methods of an enum to provide a particular behaviour.
- Enum ensure that there will never be any other instance of the class than the ones defined, without having to set a constructor as private or other tricks that can be overcome by reflection. Therefore it is a nice way to implement some patterns like the Singleton pattern.
- 他们是打字的。
- 它们带有一些有用的方法,例如 valueOf,允许通过它们的名称查找它们,或者枚举它们。
- 每个实例都可以覆盖枚举的方法以提供特定的行为。
- Enum 确保除了定义的实例之外永远不会有该类的任何其他实例,而不必将构造函数设置为私有或其他可以通过反射克服的技巧。因此,这是实现一些模式(如单例模式)的好方法。