標籤:
1:懶漢式,不保證安全執行緒
package com.yan.singleton;public class LazySingleton { private static final LazySingleton instance = null; private LazySingleton(){} public static LazySingleton getLazySingleton(){ if(null==instance){ return new LazySingleton(); } return instance; }}
2:餓漢式,安全執行緒
package com.yan.singleton;public class HungrySingleton { private HungrySingleton(){} private static final HungrySingleton instance = new HungrySingleton(); public static HungrySingleton getInstance(){ return instance; }}
3:靜態內部類,安全執行緒
package com.yan.singleton;public class InnerClassSingleton { private InnerClassSingleton(){} public static final InnerClassSingleton getInstance(){ return InnerClassSingletonHolder.INSTANCE; } private static class InnerClassSingletonHolder{ private static final InnerClassSingleton INSTANCE = new InnerClassSingleton(); }}
4:枚舉,安全執行緒,可以還原序列化(推薦此種方式)JDK1.5之後才可以使用
package com.yan.singleton;public enum EnumSingleton { INSTANCE; public void todo(){ System.out.println("todo"); }}
方式1,2,3都可以使用反射機制來破壞其單例特性,採用枚舉類型可以避免反射的破壞。
例如:
package com.yan.test;import com.yan.singleton.LazySingleton;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.util.logging.Level;import java.util.logging.Logger;public class Test { public static void main(String[] args) { Constructor<LazySingleton>cs ; try { cs = (Constructor<LazySingleton>) Class.forName("com.yan.singleton.LazySingleton") .getDeclaredConstructor(); cs.setAccessible(true);//得到私人存取權限,如果不設定,則無法執行個體化對象 LazySingleton ls = cs.newInstance(); System.out.println("===ls:"+ls); System.out.println("===ls:"+cs.newInstance()); } catch (ClassNotFoundException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); }catch (SecurityException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } catch (InstantiationException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalArgumentException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } catch (InvocationTargetException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchMethodException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } }}
Java 單例總結