标签:取出 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