单例设计
所谓的单例设计指的是一个类只允许产生一个实例化对象。
范例:
class Singleton{
public void print() {
System.out.println("hello");
}
}
public class TestSingleton{
public static void main(String args[]) {
Singleton s=null;
s=new Singleton();
}
以上的程序在进行对象实例化的时候调用了Singleton类的无参构造方法,因为在Singleton类里面并没有提供构造方法,
所以会自动生成一个无参的,什么都不做的构造方法。但是如果说现在将Singleton类中明确定义一个私有参数的构造方法
class Singleton{
private Singleton(){}//所有的方法都可以是哦那个四种权限
public void print() {
System.out.println("Hello ");
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton s=null;
s=new Singleton(); s.print();
}
}
这个时候类中已经明确的提供有一个私有的构造 ,默认的无参构造一定不会自动生成,那么也就是说此时在进行对象实例化的时候一定会有错误。
错误:Singlenton()可以在Singleton中访问private s=new Singleton();
首先一旦构造方法被私有化了,那么就表示外部无法调用构造了,也就证明外部不能产生新的实例化对象。那么就证明此时的类是一个相对而言封闭的状态。
可是现在如果还想继续调用Singleton类中的print()这个普通方法,那么就必须提供有实例化对象。
于是根据封装的特点可以考虑在类的内部产生一个实例化对象
class Singleton{
// 在类的内部是允许访问私有的结构的,所以可以在类的内部产生实例化对象
Singleton instance =new Singleton();
private Singleton(){}//所有的方法都可以是哦那个四种权限
public void print() {
System.out.println("Hello ");
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton s=null;
s.print();
}
}
现在Singleton类内部的instance对象(属性)是一个普通属性,所有的普通属性必须在有实例化对象的时候才可以进行内存空间的分配,而现在外部无法产生实例化对象,所以就必须想一个方法,可以在Singleton类没有实例化对象产生的时候也可以将instance进行使用。那么自然会联想到要使用static关键字
class Singleton{
// 在类的内部是允许访问私有的结构的,所以可以在类的内部产生实例化对象
static Singleton instance =new Singleton();
private Singleton(){}//所有的方法都可以是哦那个四种权限
public void print() {
System.out.println("Hello ");
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton s=null;
s=Singleton.instance; //static不受类的实例化对象控制且没有封装,所以可以直接访问
s.print();
}}
以上虽然可以取得了Singleton类的实例化对象,但是对于类中的属性应该使用private进行封装,
而如果想要取得封装的属性,就必须提供一个getter方法,
不过此时访问的是一个static属性,并且这个类无法在外部进行实例化对象创建,
所以应该再提供一个static方法,因为static方法也不受实例化对象的控制。
class Singleton{
private static Singleton instance =new Singleton();
public static Singleton getInstance() {
return instance; //不能加this 因为没有对象产生
}
private Singleton(){}
public void print() {
System.out.println("Hello ");
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton s=null;
s=Singleton.getInstance();
s.print();
}
}
首先现在的问题已经正常解决了,但是这样做法的目的是什么呢?只希望产生唯一的一个实例化对象。
无论在外部如何调用多少次返回都的都是用一个对象的引用,就好像windos的回收站,其实各个站都有。但是其实都是唯一的一个就好比快捷方式一样。
一个类只希望产生唯一的一个实例化对象就要用到单例设计
不过对于单例设计模式也有两类形式(引出多线程):懒汉式、饿汉式(上面写的代码)。
之前上的程序实际上就属性饿汉式的应用,因为不管是否去使用Singleton类的对象,只要该类加载了,那么一定会自动创建好一个公共的instance对象。(已经new好了)。既然是饿汉式,就希望整体的操作之中,只能够有一个实例化对象,所以一般还会为其追加上final。
面试题:请编写一个Singleton的程序并说明程序的主要特点?
· 代码在上面
·特点:构造方法私有化,外部无法产生新的实例化对象,只能够通过static方法取得实例化对象
范例:懒汉式的单例
·指的是当第一次去使用Singleton对象的时候才会为其进行实例化的处理操作。
class Singleton{
private static Singleton instance=new Singleton();
public static Singleton getInstance() {
if(instance==null) {//表示此时还没有实例化
instance=new Singleton();
}
return instance;
}
private Singleton(){}
public void print() {
System.out.println("Hello ");
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton s=null;
s=Singleton.getInstance();
s.print();
}
}
对于饿汉式和懒汉式理解就即可了,更多的情况是需要你自己将单例设计的核心组成记住,以及慢慢理解它的用法