Java Enum <T> vs T как тип переменной

Есть ли разница между этим объявлением

Thread.State state = Thread.State.NEW;

и что

Enum<Thread.State> state = Thread.State.NEW;

в Java? Вместо второго варианта немного дольше?

Ответы

Ответ 1

Два практических отличия (в отличие от причин, связанных с языком), которые приходят на ум:

  • Если вы объявите state как Enum<Thread.State>, вы не сможете передать его любым методам, ожидающим a Thread.State.
  • Если вы объявите 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>, то вы не можете использовать его в качестве ключа в карте перечисления.)

Ответ 2

Это тот же случай, что и сравнение:

Child o = someChild;

и

Parent o = someChild;

Enum - это родительский класс всех типов перечислений. Следовательно, со второй строкой код не может содержать ссылки на конкретные члены Thread.State, в частности члены, описанные в в этом разделе спецификации языка.

Ответ 3

Есть ли разница...

На практике в этом конкретном случае, вероятно, нет.

В теории Thread.State является подтипом Enum<Thread.State>. Если Thread.State объявленные (не частные) поля или методы, вы можете использовать их через первое объявление state, но не второе.

В общем, первая форма предпочтительнее... по этой причине.


Кроме того, я не думаю, что вы сможете увидеть методы enum static values() и valueOf через переменную, объявленную во втором объявлении; например.

state.valueOf("BLOCKED")

Однако вызов статического метода с помощью ссылки на экземпляр - это плохой стиль.