您的位置:首页 > 编程语言

Enum源代码解析

2018-08-03 23:44 88 查看

一简介

1.Enum源代码分析

2.关于Enum的单例模式

二.Enum源代码分析

1.类简介:

Enum是所有枚举类型的基类,包括EnumSet、EnumMap;

public abstract class Enum<E extends Enum<E>>

implements Comparable<E>, Serializable {

Enum类声明是abstract 类,但是不能被继承

我们看到作为积累Enum被继承是以下使用方式

public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>

implements Cloneable, java.io.Serializable

而不是被直接继承继承

 

那么Enum作为abstract 有在声明时有什么用处呢,答案是以下:

enum Color {RED, BLUE, GREEN}

 

编译后

public final class Color extends Enum<Color> {
  public static final Color[] values() { return (Color[])$VALUES.clone(); }
  public static Color valueOf(String name) { ... }

  private Color(String s, int i) { super(s, i); }

  public static final Color RED;
  public static final Color BLUE;
  public static final Color GREEN;

  private static final Color $VALUES[];

  static {
    RED = new Color("RED", 0);
    BLUE = new Color("BLUE", 1);
    GREEN = new Color("GREEN", 2);
    $VALUES = (new Color[] { RED, BLUE, GREEN });
  }
}

他是作为基类被继承的,然而是自动在编译后继承,这里涉及到另外两个只是点,

1> enum 作为abstract 类不能被new出来一个对象,需要通过以下方式

enum enumName{ value1,value2 method1(){} method2(){} }

2>enum 的构造方法不能被程序员调用,是提供给编译器响Enum类型的,这一点也保证了enum生来的单例模式

protected Enum(String name, int ordinal) {

this.name = name;

this.ordinal = ordinal;//这个参数一般是没什么用处,是在子类EnumSet等中使用的

}

2.成员变量

private final String name;//enum中的常量

private final int ordinal;//常量的序号,从0递增,子类EnumSet等中起到一定作用

 

3.finalize

protected final void finalize() { }

此方法在垃圾回收中使用到,对象想要逃过被回收的命运就需要在这个方法里面处理,但是这里写了空方法,并且子类不能重写。

 

4常用方法,

以enum Color {RED, BLUE, GREEN} 为例

通过Color.RED.methodName(params…)的方式调用

 

1>.toString()

public String toString() {

return name;

}

必要的时候可以覆盖方法,使用更加"programmer-friendly",程序员友好的方式

2>.equals(Object other)

public final boolean equals(Object other) {

return this==other;

}

如果常量相等返回true

3>.hashCode()

public final int hashCode() {

return super.hashCode();

}

返回常量的hash码

 

4>.compareTo(E o)

public final int compareTo(E o) {

Enum<?> other = (Enum<?>)o;

Enum<E> self = this;

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

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

throw new ClassCastException();

return self.ordinal - other.ordinal;

}

在同个Enum类中进行对比,返回ordinal的差值,注意同个Enum类对比才有意义,不同的类进行对比,可能因为序号相同,导致不同的常量相等的情况。

5>valueOf

public static <T extends Enum<T>> T valueOf(Class<T> 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的单例模式

Enum是天生的单例模式,

1.构造器只能别编译器调用,

2.实现了Serializable接口,但是不能通过序列化生成对象,如下

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");

}

3. clone()不能通过clone的方式生成对象

protected final Object clone() throws CloneNotSupportedException {

throw new CloneNotSupportedException();

}

参考资料https://www.geek-share.com/detail/2688287318.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: