单例模式的优缺点,最好能用枚举作为单例模式
1、懒汉式单例:class Singleton { private Singleton() {} private static Singleton single=null; public static Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }}Singleton通过将构造方法限定为private避免了其他类通过访问构造器进行实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过静态的getInstance()方法进行访问。 但是上面的代码是不考虑线程安全的情况下,也就是说,该实例是存在线程安全的。在并发的情况下是可能出现这种情况,就是a线程先进入getInstance()方法在创建实例化的时候,也就是还没创建成功,b线程也进入了getInstance()方法,这个时候a线程实例还没建成功,b线程判断single为空也开始创建实例,导致会出现创建出两个实例来。

3、public static Singleton getInstance() { if (single == null) { synchronized (Singleton.class) { if (single == null) { single = new Singleton(); } } } return single;}双重检查锁定,这种方式会优于上面一种方式,在并发量高的情况下,不需要排队进getInstance()方法合理利用系统资源,性能上会优于上面一种。

5、饿汉式单例:class Singleton { private Singleton() {} private static final Singleton single = new Singleton(); public static Singleton getInstance() { return single; }}饿汉式是静态加载的时候实例化,不需要担心线程安全问题。

7、结果如下,尤此可得出以上的单例无法避免反射的恶意攻击。

9、可结果却是报Exception in thread "main" java.lang.NoSuchMet茑霁酌绡hodException: com.ffcs.maintest.EnumSingleton.<init>()异常。出现这个异常的原因是因为EnumSingleton.class.getDeclaredConstructors()获取所有构造器,会发现并没有我们所设置的无参构造器,只有一个参数为(String.class,int.class)构造器,最重要的是反射在通过newInstance创建对象时,会检查该类是否ENUM修饰,如果是则抛出异常,反射失败。所以就算你反射的时候设置有参构造器也会反射失败。所以枚举是不怕反射攻击的。
