java 模式之单例模式

 

开始研究java模式,有些东西还理解的不是很透彻

 

把他们记录下来加深理解,并且跟广大技术爱好者们共同探讨

 

单例模式,就是保证在堆中只创建某一个类的一个实例,单例模式有很多应用,比如说hibernate中的SessionFactory,比如在Spring中默认创建的类的实例都应该是单例模式的。

 

我觉得他是模式中最简单的之一了

 

有两种实现方式

1:

package com.gengu.单例;

/**
 * 单例模式的一种实现形式
 * */
public class DanLi1 {

	private static  DanLi1 danLi1=null;
	
	/** 单例模式不能有公开的构造方法 */
	private DanLi1(){}
	
	/** 单例模式有一个返回对象*/
	public static DanLi1 getDanLi1(){
		if(danLi1==null){
			danLi1 = new DanLi1();
		}
		return danLi1;	
	}
}
 
package com.gengu.单例;

/**
 * 单例模式的一种实现形式
 * */
public class DanLi2 {

	private static  DanLi2 danLi2 = new DanLi2();
	
	/** 单例模式不能有公开的构造方法 */
	private DanLi2(){}
	
	/** 单例模式有一个返回对象*/
	public static DanLi2 getDanLi1(){
		return danLi2;
	}
}

 第二种方式更加线程安全,因为如果同时有两个线程都第一次访问他,那么可能在一个线程正在创建的时候另一个线程也在创建,所以建议第二种。

 

还有如果用用类加载器,加载同一个字节码文件,那么得到的Class类型的实例也是单例,请看代码

package com.gengu.单例;

public class test1 {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		Class clazz1;
		Class clazz2;
		try {
			 //加载类文件
			 clazz1= Class.forName("java.lang.String");
			 clazz2= Class.forName("java.lang.String");
			 
			 //创建实例
			 String str1=(String)clazz1.newInstance();
			 String str2=(String)clazz1.newInstance();
			 
			 System.out.println(str2.getClass());
			 System.out.println("用不同的加载器加载同一个类字节码文件是单例的clazz1==clazz2:"+(clazz1==clazz2));
			 System.out.println("但是用同一个CLass创建的两个类不是单例的str1==str2:"+(str1==str2));
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}

 class java.lang.String
用不同的加载器加载同一个类字节码文件是单例的clazz1==clazz2:true
但是用同一个CLass创建的两个类不是单例的str1==str2:false

 

以上就是今天对单例模式的一点理解

你可能感兴趣的:(java,单例,类加载)