usar recorrer que programacion estados enum como clase java enums

recorrer - ¿Por qué permitimos referirnos a un miembro de enumeración de un miembro de enum en Java?



que es un enum en java (4)

Teniendo en cuenta la siguiente enumeración:

enum Repeat { Daily, Weekly, Yearly }

Me doy cuenta de que somos capaces de escribirlo de esta manera:

Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;

que es equivalente a:

Repeat repeat = Repeat.Weekly;

¿Puedo saber por qué se permite tal sintaxis? ¿Hay alguna manera de dejar que el compilador nos advierta de esto?


¿Hay una manera de dejar que el compilador nos advierta contra esto?

Sí, use un buen IDE y active la advertencia. De esa manera, se le notificará tan pronto como escriba el código, incluso antes de compilarlo.

Por ejemplo, en Eclipse , se llama "Acceso no estático al miembro estático":


Esto se permite porque Daily, Weekly, Yearly son el campo static por default dentro de la enum y contiene el objeto de Repeat . Además, recibirá una advertencia del compilador "The static field Repeat.Weekly should be accessed in a static way" . Es similar a las siguientes líneas de código.

class Foo{ public static Foo obj1 = new Foo(); public static Foo obj2 = new Foo(); public static Foo obj3 = new Foo(); } Foo f = Foo.obj1.obj2.obj3; // will work fine but you will get a warning from the compiler.

Aquí hay una parte de la inspección de bytecode de Repeat enumeración y, a partir de esto, queda claro que la variable Enum es static y contiene el Objeto de Enum.

0: new #1 // class com/java8/demo/Repeat 3: dup 4: ldc #14 // String Daily 6: iconst_0 7: invokespecial #15 // Method "<init>":(Ljava/lang/String;I)V 10: putstatic #19 // Field Daily:Lcom/java8/demo/Repeat; 13: new #1 // class com/java8/demo/Repeat


Las instancias de enumeración son solo instancias static de la clase enum.

Tenemos dos formas de acceder al campo estático de una clase:

  1. A través de la clase itselft: Repeat.Daily
  2. A través de instancia de clase: Repeat.Daily.Daily

Cuando encadenas tu enumeración:

Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;

Es como obtener un campo estático de una instancia de una clase.


Los literales de enumeración son miembros estáticos, y con cada miembro estático, uno puede acceder a ellos usando la referencia de clase:

TypeName.staticMember TypeName.staticMethod()

O en una instancia:

new TypeName().staticMember new TypeName().staticMethod()

Se desalienta el segundo enfoque (y el compilador emitirá una advertencia)

Como los literales de enumeración son solo miembros estáticos, Repeat.Daily.Weekly.Yearly.Weekly es como el segundo fragmento de código anterior, accediendo a miembros estáticos en referencias de instancia.

Con una clase, eso sería:

class Type { static Type INSTANCE1, INSTANCE2, INSTANCE3; }

Y uno puede obtener una referencia a INSTANCE3 usando Type.INSTANCE1.INSTANCE2.INSTANCE3 . Es válido, pero es una mala práctica.