【Java基础】枚举

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

**开源地址:https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB **

36: putstatic #13 // Field Green:LColor;

39: iconst_3

40: anewarray #4 // class Color

43: dup

44: iconst_0

45: getstatic #9 // Field Red:LColor;

48: aastore

49: dup

50: iconst_1

51: getstatic #11 // Field Blue:LColor;

54: aastore

55: dup

56: iconst_2

57: getstatic #13 // Field Green:LColor;

60: aastore

61: putstatic #1 // Field $VALUES:[LColor;

64: return

}

还原后的代码如下:

public final class Color extends java.lang.Enum {

//定义的枚举成员

public static final Color Red;

public static final Color Blue;

public static final Color Green;

//编译器自动生成的 javap -c 还查不出来,疑惑

public static final /* synthetic */ Color[] $VALUES;//编译器自动生成的

public static Color[] values(){

/**

  • 0: getstatic #1 // Field $VALUES:[LColor;

  • 3: invokevirtual #2 // Method “[LColor;”.clone:()Ljava/lang/Object;

  • 6: checkcast #3 // class “[LColor;”

  • 9: areturn

*/

return $VALUES.clone();

}

public static Color valueOf(java.lang.String s){

/**

  • 0: ldc #4 // class Color

  • 2: aload_0

  • 3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljav

  • a/lang/Enum;

  • 6: checkcast #4 // class Color

  • 9: areturn

*/

return Enum.valueOf(Color.class,s);

}

protected Color(String name, int ordinal) {

super(name, ordinal);

}

static {

/**

  • 0: new #4 // class Color

  • 3: dup

  • 4: ldc #7 // String Red

  • 6: iconst_0

  • 7: invokespecial #8 // Method “”:(Ljava/lang/String;I)V

  • 10: putstatic #9 // Field Red:LColor;

*/

Red=new Color(“Red”,0);

/**

  • 13: new #4 // class Color

  • 16: dup

  • 17: ldc #10 // String Blue

  • 19: iconst_1

  • 20: invokespecial #8 // Method “”:(Ljava/lang/String;I)V

  • 23: putstatic #11 // Field Blue:LColor;

*/

Blue=new Color(“Blue”,1);

/**

  • 26: new #4 // class Color

  • 29: dup

  • 30: ldc #12 // String Green

  • 32: iconst_2

  • 33: invokespecial #8 // Method “”:(Ljava/lang/String;I)V

  • 36: putstatic #13 // Field Green:LColor;

*/

Green=new Color(“Green”,2);

/**

  • 39: iconst_3

  • 40: anewarray #4 // class Color

  • 43: dup

  • 44: iconst_0

  • 45: getstatic #9 // Field Red:LColor;

  • 48: aastore

  • 49: dup

  • 50: iconst_1

  • 51: getstatic #11 // Field Blue:LColor;

  • 54: aastore

  • 55: dup

  • 56: iconst_2

  • 57: getstatic #13 // Field Green:LColor;

  • 60: aastore

  • 61: putstatic #1 // Field $VALUES:[LColor;

*/

$VALUES=new Color[]{Red,Blue,Green};

};

}

通过上面还原后的代码可知,在类的static代码块 中编译器帮我们生成枚举中的每个成员,实际上就是生成对象并赋值给静态变量。

枚举的扩展


单例模式


枚举其实就是编译帮我们在静态代码块中创建一个或多个枚举成员对象,如果我们只定义一个枚举成员,这样就是一个单例对象

public enum Singleton {

INSTANCE;

public void doSometing(){

System.out.println(“doing”);

}

}

代码如此简单,不仅如此,这样的方式还可以解决 反射攻击 和 反序列化 导致的单例失败的问题。

避免反射攻击


在获取实例时进行了枚举判断,如果是枚举类型的则直接抛出异常。

Jdk1.8Class.clss 文件的416..417

public T newInstance(Object … initargs)

throws InstantiationException, IllegalAccessException,

IllegalArgumentException, InvocationTargetException{

if ((clazz.getModifiers() & Modifier.ENUM) != 0)

throw new IllegalArgumentException(“Cannot reflectively create enum objects”);

return inst;

}

反序列化


枚举的序列时仅降枚举对象的name属性输出到结果中,在反序列化时则是通过java.lang.EnumvalueOf 方法来根据名字在jvm中查找对象的。

同时编译器还禁止对枚举的定制化序列机制,因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。

策略模式


一种行为,多种结果,不同结果的实现,名曰策略。

public enum Calculator {

//加法运算

ADD(“+”){

public int exec(int a,int b){

return a+b;

}

},

//减法运算

SUB(“-”){

public int exec(int a,int b){

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值