wordpress转换中文版,怎样进行seo优化,流量主广告点击自助平台,手机绘图app软件下载枚举的用法 每个枚举变量其实都是枚举类的一个实例。
枚举与单例 各种模式的单例模式#xff0c;包括枚举实现的单例
//懒汉模式
class SingletonA {private static SingletonA instance new SingletonA();//保证不能通过new SingletonB的方式创建对象private SingletonA()…枚举的用法 每个枚举变量其实都是枚举类的一个实例。
枚举与单例 各种模式的单例模式包括枚举实现的单例
//懒汉模式
class SingletonA {private static SingletonA instance new SingletonA();//保证不能通过new SingletonB的方式创建对象private SingletonA(){}public static SingletonA getInstance() {return instance;}
}//保证效率的懒加载
class SingletonB {private static SingletonB instance;private SingletonB(){}public static SingletonB getInstance() {if(instance null) {synchronized (SingletonB.class) {if (instance null) {instance new SingletonB();}}}return instance;}
}//内部类懒汉模式
class SingletonC {private SingletonC(){}private static class SingletonHolder {private static final SingletonC instance new SingletonC();}public SingletonC getInstance() {return SingletonHolder.instance;}
}//内部枚举类懒加载模式
class SingletonD {private SingletonD(){}private enum EnumSingleton {instance;//因为枚举变量是static final的所以如果不是定义时声明那只能在构造方法中实例化并且有且只能实例化一次。//所以保证了resource对象的单例性。private SingletonD singletonD;private EnumSingleton() {singletonD new SingletonD();}}public SingletonD getInstance() {return EnumSingleton.instance.singletonD;}
}枚举如何比较 可以用equals()也可以用推荐使用 enum的equals()方法实现如下
public final boolean equals(Object other) {return thisother;}可以看出也是调用的实现的。 官方文档说明如下
JLS 8.9 Enums 一个枚举类型除了定义的那些枚举常量外没有其他实例了。 试图明确地说明一种枚举类型是会导致编译期异常。
在枚举中final clone方法确保枚举常量从不会被克隆而且序列化机制会确保从不会因为反序列化而创造复制的实例。
枚举类型的反射实例化也是被禁止的。
总之以上内容确保了除了定义的枚举常量之外没有枚举类型实例。另外和equals()的不同如下 不会抛出 NullPointerException
enum Color { BLACK, WHITE };Color nothing null;
if (nothing Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException 在编译期检测类型兼容性
enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK Chiral.LEFT); // DOESNT COMPILE!!! Incompatible types!总而言之在枚举比较上使用 因为 1. 能正常工作 2. 更快 3. 编译期是安全的 4. 运行时也是安全的
switch 对枚举的支持 枚举 switchcase 标签必须为枚举常量的非限定名称 用法如下
//定义枚举
public enum Color {RED,GREEN,YELLOW;
}//使用枚举
public void compare(Color color) {switch (color) {case RED:break;case YELLOW:break; default:break;}}枚举的线程安全性问题 枚举的序列化如何实现 枚举是线程安全的描述如下
1枚举的实现方式
//定义枚举
public enum t {SPRING,SUMMER,AUTUMN,WINTER;
}
//反编译枚举类
public final class T extends Enum
{private T(String s, int i){super(s, i);}public static T[] values(){T at[];int i;T at1[];System.arraycopy(at ENUM$VALUES, 0, at1 new T[i at.length], 0, i);return at1;}public static T valueOf(String s){return (T)Enum.valueOf(demo/T, s);}public static final T SPRING;public static final T SUMMER;public static final T AUTUMN;public static final T WINTER;private static final T ENUM$VALUES[];static{SPRING new T(SPRING, 0);SUMMER new T(SUMMER, 1);AUTUMN new T(AUTUMN, 2);WINTER new T(WINTER, 3);ENUM$VALUES (new T[] {SPRING, SUMMER, AUTUMN, WINTER});}
}
通过反编译后代码我们可以看到public final class T extends Enum说明该类是继承了Enum类的同时final关键字告诉我们这个类也是不能被继承的。 并且方法与属性都是static的而static类型的属性会在类被加载之后被初始化。当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以创建一个enum类型是线程安全的。
2枚举的序列化 JavaDoc中的描述
序列化的时候Java仅仅是将枚举对象的name属性输出到结果中
反序列化的时候则是通过java.lang.Enum的valueOf方法来根据名字查找枚举对象。
同时编译器是不允许任何对这种序列化机制的定制的
因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。
我们看一下这个valueOf方法
public static T extends EnumTT valueOf(ClassT 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 const enumType . name); }从代码中可以看到代码会尝试从调用enumType这个Class对象的enumConstantDirectory()方法返回的map中获取名字为name的枚举对象如果不存在就会抛出异常。再进一步跟到enumConstantDirectory()方法就会发现到最后会以反射的方式调用enumType这个类型的values()静态方法也就是上面我们看到的编译器为我们创建的那个方法然后用返回结果填充enumType这个Class对象中的enumConstantDirectory属性。
所以JVM对序列化有保证。 此段描述来自于http://blog.jobbole.com/94074/