关于java的枚举
作者:互联网
- java的枚举倒是一直在使用,但没有深究过,最近看guava的代码里,发现大量使用枚举,于是详细看了下。
- 首先java的枚举实际上是语法糖,本质上还是class,编译之后就与class无异。那既然是class,当然也具有class的一些特性,如继承,实现接口等。
- 关键字enum定义的枚举类型,实际上都是abstract class Enums的子类。而Enums类中定义了name ordinal字段和一些方法,这也是为什么我们在任何枚举的定义里都可以使用这些方法的原因。
- 一个典型的枚举的定义如下:
public enum Ordinals {
FIRST("st"),
SECOND("nd"),
THIRD("rd");
private String notation;
private Ordinals(String notation) {
this.notation = notation;
}
public String getNotation() {
return notation;
}
}
- 在编译之后的结果为
public final class Ordinals extends java.lang.Enum<Ordinals> {
public static final Ordinals FIRST;
public static final Ordinals SECOND;
public static final Ordinals THIRD;
private java.lang.String notation; // your custom field
private static final Ordinals[] $VALUES; // all enum constants
public static Ordinals[] values(); // every enum class has this static method
Code:
0: getstatic #1 // Field $VALUES:[LOrdinals;
3: invokevirtual #2 // Method "[LOrdinals;".clone:()Ljava/lang/Object;
6: checkcast #3 // class "[LOrdinals;"
9: areturn
public static Ordinals valueOf(java.lang.String); // every enum class has this static method
Code:
0: ldc_w #4 // class Ordinals
3: aload_0
4: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
7: checkcast #4 // class Ordinals
10: areturn
private Ordinals(java.lang.String);
Code:
0: aload_0
1: aload_1
2: iload_2
3: invokespecial #6 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
6: aload_0
7: aload_3
8: putfield #7 // Field notation:Ljava/lang/String;
11: return
public java.lang.String getNotation();
Code:
0: aload_0
1: getfield #7 // Field notation:Ljava/lang/String;
4: areturn
static {}; // fills the $VALUES array and initializes the static fields corresponding to the enum constants
Code:
0: new #4 // class Ordinals
3: dup
4: ldc #8 // String FIRST
6: iconst_0
7: ldc #9 // String st
9: invokespecial #10 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
12: putstatic #11 // Field FIRST:LOrdinals;
15: new #4 // class Ordinals
18: dup
19: ldc #12 // String SECOND
21: iconst_1
22: ldc #13 // String nd
24: invokespecial #10 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
27: putstatic #14 // Field SECOND:LOrdinals;
30: new #4 // class Ordinals
33: dup
34: ldc #15 // String THIRD
36: iconst_2
37: ldc #16 // String rd
39: invokespecial #10 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
42: putstatic #17 // Field THIRD:LOrdinals;
45: iconst_3
46: anewarray #4 // class Ordinals
49: dup
50: iconst_0
51: getstatic #11 // Field FIRST:LOrdinals;
54: aastore
55: dup
56: iconst_1
57: getstatic #14 // Field SECOND:LOrdinals;
60: aastore
61: dup
62: iconst_2
63: getstatic #17 // Field THIRD:LOrdinals;
66: aastore
67: putstatic #1 // Field $VALUES:[LOrdinals;
70: return
}
- translate back to java
public final class Ordinals extends java.lang.Enum<Ordinals> {
public static final Ordinals FIRST;
public static final Ordinals SECOND;
public static final Ordinals THIRD;
private String notation;
private static final Ordinals[] $VALUES;
public static Ordinals[] values() {
return $VALUES.clone();
}
public static Ordinals valueOf(String name) {
return (Ordinals) Enum.valueOf(Ordinals.class, name);
}
private Ordinals(String name, int ordinal, String notation) {
super(name, ordinal);
this.notation = notation
}
static {
FIRST = new Ordinals("FIRST", 0, "st");
SECOND = new Ordinals("SECOND", 1, "nd");
THIRD = new Ordinals("THIRD", 2, "rd");
Ordinals[] $VALUES = new Ordinals[3];
$VALUES[0] = FIRST;
$VALUES[1] = SECOND;
$VALUES[2] = THIRD;
Ordinals.$VALUES = $VALUES;
}
}
- 对比最开始的enum的定义,可以看到,通过enum的语法糖,java帮我们做了什么
- 默认继承Enum类,于是可以使用Enum类中定义的方法
- 枚举的每个item 都被定义成一个静态变量,且在静态代码块中被初始化。
- 定义了一个values数组,将item填充
- 枚举的使用场景
- 和常量相比,可做语法检查
- 单例模式
- 一个枚举实现的单例如下
public enum Signleton {
INSTANCE;
public void dosomething() {
}
}
- guava中的典型用法,基本是用作单例+内部类。
private static enum NullEntry implements LocalCache.ReferenceEntry<Object, Object> {
INSTANCE;
private NullEntry() {
}
public LocalCache.ValueReference<Object, Object> getValueReference() {
return null;
}
public void setValueReference(LocalCache.ValueReference<Object, Object> valueReference) {
}
public LocalCache.ReferenceEntry<Object, Object> getNext() {
return null;
}
}
static enum Strength {
STRONG {
<K, V> LocalCache.ValueReference<K, V> referenceValue(LocalCache.Segment<K, V> segment, LocalCache.ReferenceEntry<K, V> entry, V value, int weight) {
return (LocalCache.ValueReference)(weight == 1 ? new LocalCache.StrongValueReference(value) : new LocalCache.WeightedStrongValueReference(value, weight));
}
Equivalence<Object> defaultEquivalence() {
return Equivalence.equals();
}
},
SOFT {
<K, V> LocalCache.ValueReference<K, V> referenceValue(LocalCache.Segment<K, V> segment, LocalCache.ReferenceEntry<K, V> entry, V value, int weight) {
return (LocalCache.ValueReference)(weight == 1 ? new LocalCache.SoftValueReference(segment.valueReferenceQueue, value, entry) : new LocalCache.WeightedSoftValueReference(segment.valueReferenceQueue, value, entry, weight));
}
Equivalence<Object> defaultEquivalence() {
return Equivalence.identity();
}
},
WEAK {
<K, V> LocalCache.ValueReference<K, V> referenceValue(LocalCache.Segment<K, V> segment, LocalCache.ReferenceEntry<K, V> entry, V value, int weight) {
return (LocalCache.ValueReference)(weight == 1 ? new LocalCache.WeakValueReference(segment.valueReferenceQueue, value, entry) : new LocalCache.WeightedWeakValueReference(segment.valueReferenceQueue, value, entry, weight));
}
Equivalence<Object> defaultEquivalence() {
return Equivalence.identity();
}
};
private Strength() {
}
abstract <K, V> LocalCache.ValueReference<K, V> referenceValue(LocalCache.Segment<K, V> var1, LocalCache.ReferenceEntry<K, V> var2, V var3, int var4);
abstract Equivalence<Object> defaultEquivalence();
}
标签:lang,java,String,Ordinals,枚举,static,关于,public,LocalCache 来源: https://www.cnblogs.com/noooone/p/15464172.html