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

есть ли разница между настоящей декларации

Thread.State state = Thread.State.NEW;

и

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

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

3 ответов


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

  1. если вы объявляете state Как Enum<Thread.State>, тогда вы не сможете передать его любым методам, которые ожидают 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>>. Вместо этого ты!--26-->должны пишите EnumMap<Thread.State, String>. Итак, это пример различия #1, о котором я упоминал выше: если вы объявите state Как Enum<Thread.State>, тогда вы не можете использовать его как ключ в enum-map.)


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

Child o = someChild;

и

Parent o = someChild;

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


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

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

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

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


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

state.valueOf("BLOCKED")

однако вызов статического метода через ссылку на экземпляр является плохим стилем.