前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何写出更好的Java单例(Singleton)模式,以及单例模式的攻防源代码

如何写出更好的Java单例(Singleton)模式,以及单例模式的攻防源代码

作者头像
Jerry Wang
发布2020-04-29 16:32:07
3540
发布2020-04-29 16:32:07
举报
代码语言:javascript
复制
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;  
    }  
}

代码语言:javascript
复制
package singleton;

public enum JerrySingletonAnotherApproach {
	INSTANCE ;  
	
	private String name = "Jerry" ;
	 
	public String getName() {  
	    return this.name;  
	}  
}

代码语言:javascript
复制
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;  
    }  
}

代码语言:javascript
复制
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();
    }  

}

代码语言:javascript
复制
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();
	}
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-04-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档