标签:取出 bool 不同类 线程安全的单例模式 getname method .class 默认 amp
疑问,常量为什么要用Enum 定义,而不用final 来定义一个成员变量或者在Interface 中定义常量?
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable
enum enumName{ value1, value2; method1(){}; method2(){}; }
其次,看到抽象类,第一印象是肯定可以继承,但是很抱歉,Enum 类是无法被继承的,为什么一个抽象类无法被继承?enum 定义的枚举类是怎么来的?难道不是对Enum 的一种继承吗?带着这些疑问我们来反编译以下代码。
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 }); } }
从反编译之后的代码中,我们发现,编译器不让我们继承Enum,但是当我们使用enum关键字定义一个枚举的时候,他会帮我们在编译后默认继承java.lang.Enum类,而不像其他的类一样默认继承Object类。且采用enum声明后,该类会被编译器加上final声明,故该类是无法继承的。 PS:由于JVM类初始化是线程安全的,所以可以采用枚举类实现一个线程安全的单例模式。
private final String name; public final String name() { return name; } private final int ordinal; public final int ordinal() { return ordinal; }
protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; }
文章开头反编译的代码中private Color(String s, int i) { super(s, i); }中的super(s, i);就是调用Enum中的这个保护类型的构造函数来初始化name和ordinal。
public String toString() { return name; } public final boolean equals(Object other) { return this == other; } public final int hashCode() { return super.hashCode(); } 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; } public final Class<E> getDeclaringClass() { Class clazz = getClass(); Class zuper = clazz.getSuperclass(); return (zuper == Enum.class) ? clazz : zuper; }
public enum CommandToken implements BaseEnum { TECH(5, "/152", "/tech"), ZHINENG(6, "/152/153", "/tech/zhineng"), JIANKANG(7, "/154", "/jiankang"), YINSHI(8, "/154/155", "/jiankang/yinshi"), MONEY(9, "/156", "/money"), YINHANG(10, "/156/157", "/money/yinhang"); private int value; // 命令值 private String url; // 匹配的url private String catagory; // 替换的目录 private CommandToken(int value, String url, String catagory) { this.value = value; this.url = url; this.catagory = catagory; } public int getValue() { return value; } public String getUrl() { return url; } public String getCatagory() { return catagory; } public static CommandToken parse(String value) { CommandToken[] vs = values();//values() 其实就是 CommandToken.values(); 一个编译器自动产生的静态方法 for (CommandToken s : vs) { if (value.equals(s.url)) { return s; } } return null; } @Override public String toString() { return catagory; } @Override public int toInt() { // TODO Auto-generated method stub return 0; } } public String getColumnPath(String url){ String columnPathTem = null; CommandToken token = CommandToken.parse(url); if(token != null){ columnPathTem = token.toString(); }else{ columnPathTem = null; } return columnPathTem; }
public interface BaseEnum { /** * 返回该对象的字符串表示 * @return 字符串 */ public String toString(); /** * 返回该对象的整型表示 * @return 整型 */ public int toInt() ; }
public enum TypeEnum implements BaseEnum { // VIDEO(1, "视频") --> VIDEO = new TypeEnum(1,"视频") VIDEO(1, "视频"), AUDIO(2, "音频"), TEXT(3, "文本"), IMAGE(4, "图像"); // 成员变量 private int value; private String name; // 构造方法,自定义,在enum实例序列的最后添加一个分号,而且 Java 要求必须先定义 enum 实例(例如VIDEO) TypeEnum(int value, String name) { this.value = value; this.name = name; } // 提供访问的get set 方法 public int getValue() { return value; } public String getName() { return name; } public void setValue(int value) { this.value = value; } public void setName(String name) { this.name = name; } // 普通方法 public static TypeEnum getByValue(int value) { for (TypeEnum typeEnum : TypeEnum.values()) { if (typeEnum.value == value) { return typeEnum; } } throw new IllegalArgumentException("No element matches " + value); } // 覆盖Object类的 toString 方法 public String toString() { return this.value + "_" + this.name; } // 实现接口方法,因为Java 不支持多继承,因此只能通过实现接口 @Override public int toInt() { // TODO Auto-generated method stub return 0; } }
标签:取出 bool 不同类 线程安全的单例模式 getname method .class 默认 amp
原文地址:https://www.cnblogs.com/hellovoyager1/p/9121035.html