Java Enum类型浅析

今天在code的时候看到如下定义的Enum类型,觉得很奇怪:

public enum Sex {
	NONE {
		@Override
		public String getName() {
			// TODO Auto-generated method stub
			return "空";
		}
	},
	MAN {
		@Override
		public String getName() {
			// TODO Auto-generated method stub
			return "男";
		}
	},
	WOMEN {
		@Override
		public String getName() {
			// TODO Auto-generated method stub
			return "女";
		}
	};
	
	public abstract String getName();
}

      印象中Enum类型应该是被翻译成final的类,而每个成员应该都是此类的实例,为什么还能加入abstract方法,而且还能被重写呢.

随后又写了一个类:

State:

public enum State {
	
	BUSY,
	LEISURE;
	
}

     然后使用javap -p命令反编译了一下两个枚举对象生成的.class文件:

     首先是Sex.class,反编译结果如下:

//Compiled from "Sex.java"
public abstract class test.he.enumeration.Sex extends java.lang.Enum<test.he.enumeration.Sex> {
  public static final test.he.enumeration.Sex NONE;
  public static final test.he.enumeration.Sex MAN;
  public static final test.he.enumeration.Sex WOMEN;
  private static final test.he.enumeration.Sex[] $VALUES;
  public static test.he.enumeration.Sex[] values();
  public static test.he.enumeration.Sex valueOf(java.lang.String);
  private test.he.enumeration.Sex();
  public abstract java.lang.String getName();
  test.he.enumeration.Sex(java.lang.String, int, test.he.enumeration.Sex$1);
  static {};
}
    1. 发现这里的Sex类被声明成abstract的了.

     2.而且还发现系统还生成了另外3个.class文件:Sex$1.class、Sex$2.class和Sex$3.class


     编译其中一个Sex$1.class:

//Compiled from "Sex.java"
final class test.he.enumeration.Sex$1 extends test.he.enumeration.Sex {
  test.he.enumeration.Sex$1(java.lang.String, int);
  public java.lang.String getName();
}

     3.注意到这里的Sex$1已经变成包访问权限,而且被声明了final,并且继承了Sex


     再使用jd-gui反编译Sex$1.class:

 enum Sex$1
{
  Sex$1()
  {
    super(str, i, null);
  }

  public String getName() {
    return "空";
  }
}
     4.这个其实就是我们重写后的新的enum类,构造方法也是包访问权限

     随后反编译了State.class文件:

//Compiled from "State.java"
public final class test.he.enumeration.State extends java.lang.Enum<test.he.enum
eration.State> {
  public static final test.he.enumeration.State BUSY;
  public static final test.he.enumeration.State LEISURE;
  private static final test.he.enumeration.State[] $VALUES;
  public static test.he.enumeration.State[] values();
  public static test.he.enumeration.State valueOf(java.lang.String);
  private test.he.enumeration.State();
  static {};
}

     5.发现这里的对象直接被声明成了final.


试着把abstract方法删除,直接在对象后面定义方法,发现反编译的结果大致一致

只是Sex没被声明任何关键字:public class Sex

可以理解为Sex中,可以有自己的对象,也可以有自己子类的对象,所以未声明任何关键字

在一般情况下,需要把共有方法声明为abstract方法,

 因为从public static final test.he.enumeration.Sex NONE;可以知道,这里利用了多态性,在外部访问NONE时,只能访问Sex中存在的方法

 其实测试一下可以发现,不需要将方法声明为abstract方法也可以访问,但是使用abstract有更好的强制性,让子类必须重写这个方法


从上面的众多结果可以发现,Enum中的每个属性都是 该类(A)的实例/该类的子类(B extends A)的实例

向Enum类(A)中的属性中添加方法或属性,该类(A)就不会被(abstract或者正常)声明为final,并且产生继承自该类的子类(B extends A),而该属性就会成为子类(B)的对象.

好吧有点绕口......不会说......

如果这个浅析有错误,希望大家指正



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值