关于java的枚举

发布时间:2022-07-02 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了关于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();
    }

脚本宝典总结

以上是脚本宝典为你收集整理的关于java的枚举全部内容,希望文章能够帮你解决关于java的枚举所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。