package singleton; public class JerrySingleton { @SuppressWarnings("unused") private String name; private JerrySingleton(){ name = "Jerry"; } private static class SingletonHolder{ private static final JerrySingleton INSTANCE = new JerrySingleton(); } public static JerrySingleton getInstance() { return SingletonHolder.INSTANCE; } }
package singleton; public enum JerrySingletonAnotherApproach { INSTANCE ; private String name = "Jerry" ; public String getName() { return this.name; } }
package singleton; public class JerrySingletonImproved { private static boolean flag = false; private JerrySingletonImproved(){ synchronized(JerrySingletonImproved.class) { if(flag == false) { flag = !flag; } else { throw new RuntimeException("Singleton violated"); } } } private static class SingletonHolder{ private static final JerrySingletonImproved INSTANCE = new JerrySingletonImproved(); } public static JerrySingletonImproved getInstance() { return SingletonHolder.INSTANCE; } }
package singleton; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class SingletonAttack { @SuppressWarnings("unused") private static void test1() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { Class<?> classType = JerrySingleton.class; Constructor<?> c = classType.getDeclaredConstructor(JerrySingleton.class); c.setAccessible(true); JerrySingleton e1 = (JerrySingleton)c.newInstance(); JerrySingleton e2 = JerrySingleton.getInstance(); System.out.println(e1 == e2); } private static void test2() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { Class<?> classType = JerrySingletonImproved.class; Constructor<?> c = classType.getDeclaredConstructor(); c.setAccessible(true); JerrySingletonImproved e1 = (JerrySingletonImproved)c.newInstance(); JerrySingletonImproved e2 = JerrySingletonImproved.getInstance(); System.out.println(e1 == e2); } @SuppressWarnings("unused") private static void test3() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { Class<?> classType = JerrySingletonAnotherApproach.class; Constructor<?> c = classType.getDeclaredConstructor(); c.setAccessible(true); JerrySingletonAnotherApproach e1 = (JerrySingletonAnotherApproach)c.newInstance(); JerrySingletonAnotherApproach e2 = JerrySingletonAnotherApproach.INSTANCE; System.out.println(e1 == e2); } public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { test2(); System.out.println("Name:" + JerrySingletonAnotherApproach.INSTANCE.getName()); // test3(); } }
package singleton; public class SingletonInnerClass { /* * 当执行getInstance()方法的时候就去调用FileIOHolder内部类里面的INSTANCE实例, * 此时FileIOHolder内部类会被加载到内存里,在类加载的时候就对INSTANCE实例进行初始化。 * 和饿汉式一个道理,保证了只有一个实例,而且在调用getInstance()方法的时候才进行INSTANCE实例的初始化, * 又具有懒汉式的部分特性。” */ private static final class FileIOHolder { private static final SingletonInnerClass INSTANCE = new SingletonInnerClass(); } private SingletonInnerClass() { System.out.println("constructor of SingletonInnerClass..."); } public static SingletonInnerClass getInstance() { String trimTest = new String("i042416").trim(); System.out.println("GetInstance called..." + trimTest); return FileIOHolder.INSTANCE; } private static void objectTest(){ Object obj = new Object(); Class<? extends Object> clas = obj.getClass(); System.out.println(clas.getClassLoader()); } public static void main(String arg[]){ Object obj1 = SingletonInnerClass.getInstance(); Object obj2 = SingletonInnerClass.getInstance(); System.out.println(obj1 == obj2); objectTest(); } }