Java Enum <T> vs T作为变量类型

k13*_*13i 14 java generics enums difference

这个声明之间有什么区别吗?

Thread.State state = Thread.State.NEW;
Run Code Online (Sandbox Code Playgroud)

然后

Enum<Thread.State> state = Thread.State.NEW;
Run Code Online (Sandbox Code Playgroud)

在Java?而不是第二个选项有点长?

man*_*uti 14

这与以下两者之间的比较情况相同:

Child o = someChild;
Run Code Online (Sandbox Code Playgroud)

和

Parent o = someChild;
Run Code Online (Sandbox Code Playgroud)

Enum是所有枚举类型的父类.因此,对于第二行,代码不能包含对特定成员的引用,特别是语言规范的本节中Thread.State描述的成员.


Ste*_*n C 8

有什么不同......

在实践中,在这种特殊情况下,可能没有.

从理论上讲,Thread.State是一个子类型Enum<Thread.State>.如果Thread.State声明(非私有)字段或方法,那么您可以通过第一个声明使用它们state,但不能使用第二个声明.

一般来说,第一种形式是优选的......因此.


另外,我不认为你将能够看到一个枚举的static方法values(),并valueOf通过在第二个声明中声明的变量; 例如

state.valueOf("BLOCKED")
Run Code Online (Sandbox Code Playgroud)

但是,通过实例引用调用静态方法是错误的样式.


rua*_*akh 3

我想到了两个实际差异(与语言法律原因相反):

  1. 如果您声明state为 an Enum<Thread.State>,那么您将无法将其传递给任何需要 a 的方法Thread.State。
  2. 如果您声明state为Enum<Thread.State>,您会让读者(无论将来需要接触此代码的人)想知道为什么要这样编写它。

这些都不是一个非常深刻的原因。我们可以很容易地想象一个平行宇宙,其中大多数人使用Enum<Thread.State>而不是Thread.State,就像(在我们的宇宙中)大多数人使用List<...>而不是ArrayList<...>(如果可能的话)。但由于大多数人在我们的宇宙中不会这样做,因此您最好遵循通用模式,以最大程度地减少混乱和意外不兼容的风险。


顺便说一句,以防万一这将是您的下一个问题。。。您使用的主要情况Enum是当您想要编写适用于许多不同枚举类型的通用内容时。JDK 中的一个例子是EnumMap<K extends Enum<K>,V>,它是一种特殊的映射实现,通过知道其键是枚举值而获得空间和性能优势。

(顺便请注意,你不能写EnumMap<Enum<Thread.State>, String>,因为Enum<Thread.State>不扩展Enum<Enum<Thread.State>>。相反,你必须写EnumMap<Thread.State, String>。所以这是我上面提到的差异#1的一个例子:如果你声明state为Enum<Thread.State>,那么你不能将其用作枚举映射中的键。)