Я только сейчас понимаю их силу и полезность в использовании класса Constants... но мне очень интересно знать, как они реализованы под капотом. Они, похоже, работают как статический метод или статическая константа, поскольку вы просто импортируете файл, который "владеет" перечислением, и вы можете сделать ссылку на них, используя enumName.valueName
. Кажется, что в Javadocs они представляют собой class
, но кажется странным иметь "неназванный" класс по требованию. (В Java хотя бы...)
Как перечислены перечисления в Java?
Ответ 1
Я считаю, что каждый экземпляр перечисления является анонимным окончательным подклассом перечисления.
декомпилировать:
public enum Color {
r(0xff0000), g(0x00ff00), b(0x0000ff);
Color(int rgb) {
this.rgb=rgb;
}
final int rgb;
}
и вы можете увидеть созданные экземпляры:
D:\home\ray\dev\indigoapps\so8032067enumimpl\bin>javap -c Color
Compiled from "Color.java"
public final class Color extends java.lang.Enum{
public static final Color r;
public static final Color g;
public static final Color b;
final int rgb;
static {};
Code:
0: new #1; //class Color
3: dup
4: ldc #16; //String r
6: iconst_0
7: ldc #17; //int 16711680
9: invokespecial #18; //Method "<init>":(Ljava/lang/String;II)V
12: putstatic #22; //Field r:LColor;
15: new #1; //class Color
18: dup
19: ldc #24; //String g
21: iconst_1
22: ldc #25; //int 65280
24: invokespecial #18; //Method "<init>":(Ljava/lang/String;II)V
27: putstatic #26; //Field g:LColor;
30: new #1; //class Color
33: dup
34: ldc #28; //String b
36: iconst_2
37: sipush 255
40: invokespecial #18; //Method "<init>":(Ljava/lang/String;II)V
43: putstatic #29; //Field b:LColor;
46: iconst_3
47: anewarray #1; //class Color
50: dup
51: iconst_0
52: getstatic #22; //Field r:LColor;
55: aastore
56: dup
57: iconst_1
58: getstatic #26; //Field g:LColor;
61: aastore
62: dup
63: iconst_2
64: getstatic #29; //Field b:LColor;
67: aastore
68: putstatic #31; //Field ENUM$VALUES:[LColor;
71: return
public static Color[] values();
Code:
0: getstatic #31; //Field ENUM$VALUES:[LColor;
3: dup
4: astore_0
5: iconst_0
6: aload_0
7: arraylength
8: dup
9: istore_1
10: anewarray #1; //class Color
13: dup
14: astore_2
15: iconst_0
16: iload_1
17: invokestatic #43; //Method java/lang/System.arraycopy:(Ljava/lang/Obj
ect;ILjava/lang/Object;II)V
20: aload_2
21: areturn
public static Color valueOf(java.lang.String);
Code:
0: ldc #1; //class Color
2: aload_0
3: invokestatic #51; //Method java/lang/Enum.valueOf:(Ljava/lang/Class;L
java/lang/String;)Ljava/lang/Enum;
6: checkcast #1; //class Color
9: areturn
}
Ответ 2
Если вам интересно, как они реализованы под капотом, а не то, что вы можете с ними сделать, просто посмотрите их определение.
Отредактируйте 4 года на: Grr, ненадежные 4-летние ссылки... Я не нашел хорошую текущую ссылку на источник, но вы всегда можете найти ее в своем собственном jdk или просто используйте обратный путь.
Ответ 3
Перечисления статически создаются, когда класс перечисления сначала загружается и неизменен.
У вас должен быть конструктор в классе enum, если вы хотите назначить разные значения для вашего перечисления. После завершения конструктора вы не можете изменить значение перечислений (неизменяемое, как указано).
Вам не нужно использовать метод equals() для перечислений: оператор == будет работать нормально.
Я написал учебное пособие в своем блоге, в котором показано, как использовать класс enum, но это не так просто, просто прочитав ссылку enum.
если вам интересно, это ссылка. Блог