java enum原理_Java枚举的实现原理

Java的枚举类,一般的常用方式是使用枚举代表各类选项,既限定了接受值的范围,又便于记忆。如使用枚举定义星期几、性别等等。

看一个最简单的枚举:

public enum SimpleEnum {

MONDAY, TUESDAY;

}

在使用这个枚举时,我们可以使用以下的方法:

SimpleEnum.TUESDAY.name();

SimpleEnum.MONDAY.ordinal();

SimpleEnum.values();

SimpleEnum.valueOf("WEDNESDAY");

反编译看一下:

Compiled from "SimpleEnum.java"

// 说明enum定义的枚举,是java.lang.Enum类的子类

public final class jdk.test.Enum.SimpleEnum extends java.lang.Enum {

private SimpleEnum(String s, int i)

{

super(s, i);

}

public static SimpleEnum[] values()

{

SimpleEnum asimpleenum[];

int i;

SimpleEnum asimpleenum1[];

System.arraycopy(asimpleenum = ENUM$VALUES, 0, asimpleenum1 = new SimpleEnum[i = asimpleenum.length], 0, i);

return asimpleenum1;

}

public static SimpleEnum valueOf(String s)

{

return (SimpleEnum)Enum.valueOf(jdk/test/Enum/SimpleEnum, s);

}

public static final SimpleEnum MONDAY;

public static final SimpleEnum TUESDAY;

private static final SimpleEnum ENUM$VALUES[];

static

{

MONDAY = new SimpleEnum("MONDAY", 0);

TUESDAY = new SimpleEnum("TUESDAY", 1);

ENUM$VALUES = (new SimpleEnum[] {

MONDAY, TUESDAY

});

}

}

再看一下java.lang.Enum类的源码:

public abstract class Enum> implements Comparable, Serializable {

// Enum的私有属性,name,结合字节码,name属性的值就是实例对象的变量名的String

private final String name;

public final String name() {

return name;

}

// 序号值,从0开始 ,static初始化块中操作

private final int ordinal;

public final int ordinal() {

return ordinal;

}

protected Enum(String name, int ordinal) {

this.name = name;

this.ordinal = ordinal;

}

public String toString() {

return name;

}

public final boolean equals(Object other) {

return this==other;

}

public final int hashCode() {

return super.hashCode();

}

/**

* Throws CloneNotSupportedException. This guarantees that enums

* are never cloned, which is necessary to preserve their "singleton"

* status.

*

* @return (never returns)

*/

protected final Object clone() throws CloneNotSupportedException {

throw new CloneNotSupportedException();

}

public final int compareTo(E o) {

Enum> other = (Enum>)o;

Enum self = this;

if (self.getClass() != other.getClass() && // optimization

self.getDeclaringClass() != other.getDeclaringClass())

throw new ClassCastException();

return self.ordinal - other.ordinal;

}

@SuppressWarnings("unchecked")

public final Class getDeclaringClass() {

Class> clazz = getClass();

Class> zuper = clazz.getSuperclass();

return (zuper == Enum.class) ? (Class)clazz : (Class)zuper;

}

public static > T valueOf(Class enumType,

String name) {

T result = enumType.enumConstantDirectory().get(name);

if (result != null)

return result;

if (name == null)

throw new NullPointerException("Name is null");

throw new IllegalArgumentException(

"No enum constant " + enumType.getCanonicalName() + "." + name);

}

/**

* enum classes cannot have finalize methods.

*/

protected final void finalize() { }

/**

* prevent default deserialization

*/

private void readObject(ObjectInputStream in) throws IOException,

ClassNotFoundException {

throw new InvalidObjectException("can't deserialize enum");

}

private void readObjectNoData() throws ObjectStreamException {

throw new InvalidObjectException("can't deserialize enum");

}

}

实际上看来,enum只是类的一种特殊形式,它实际上和普通的类没有什么区别,只是JVM将他区别对待,让他在定义时可以以特殊的形式来进行,其他事情交给了JVM。

而且,有趣的是,Enum这个抽象类,我们是无法通过继承它来创造自己的实现类的。

话说回来,既然枚举和正常类没有什么区别,那是不是可以像普通类定义构造器,各种方法,私有属性呢?

事实证明,当然是可以的。

可以实现接口

可以定义属性和方法

不可以显式的调用其构造器(因为是private)

不可以继承类(因为暗含父类了)

可以定义抽象方法,且定义抽象方法时,enum反编译是抽象类。

例:

public interface IEnum {

void test();

}

public enum MyEnum implements IEnum {

ONE(1) {

@Override

void what() {

// TODO Auto-generated method stub

}

},

TWO(2) {

@Override

void what() {

// TODO Auto-generated method stub

}

};

private int num;

abstract void what();

MyEnum(int num) {

this.setNum(num);

}

public int getNum() {

return num;

}

public void setNum(int num) {

this.num = num;

}

@Override

public void test() {

System.out.println("test");

}

}

// decomplie

public abstract class MyEnum extends Enum

implements IEnum

{

private MyEnum(String s, int i)

{

super(s, i);

FIVE.num = 5;

}

abstract void what();

private MyEnum(String s, int i, int num)

{

super(s, i);

setNum(num);

FIVE.num = 5;

}

public MyEnum getFive()

{

return FIVE;

}

public int getNum()

{

return num;

}

public void setNum(int num)

{

this.num = num;

}

public void test()

{

System.out.println("test");

}

public static MyEnum[] values()

{

MyEnum amyenum[];

int i;

MyEnum amyenum1[];

System.arraycopy(amyenum = ENUM$VALUES, 0, amyenum1 = new MyEnum[i = amyenum.length], 0, i);

return amyenum1;

}

public static MyEnum valueOf(String s)

{

return (MyEnum)Enum.valueOf(jdk/test/Enum/MyEnum, s);

}

MyEnum(String s, int i, int j, MyEnum myenum)

{

this(s, i, j);

}

public static final MyEnum ONE;

public static final MyEnum TWO;

private int num;

private MyEnum FIVE;

private static final MyEnum ENUM$VALUES[];

static

{

ONE = new MyEnum("ONE", 0, 1) {

void what()

{

}

}

;

TWO = new MyEnum("TWO", 1, 2) {

void what()

{

}

}

;

ENUM$VALUES = (new MyEnum[] {

ONE, TWO

});

}

}

class MyEnum$1 extends MyEnum

{

void what()

{

}

MyEnum$1(String s, int i, int $anonymous0)

{

super(s, i, $anonymous0, null);

}

}

class MyEnum$2 extends MyEnum

{

void what()

{

}

MyEnum$2(String s, int i, int $anonymous0)

{

super(s, i, $anonymous0, null);

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值