问题的引出
当对一个类的构造方法进行私有化以后,我们不能以new的形式新建一个对象,去调用对象的方法。如下:
class Singleton{
private Singleton(){
}
public void print(){
System.out.println("hello world");
}
}
这个时候我们调用print()
方法,需要如下:
@Test
public void test(){
Singleton s1 = null;
s1 = new Singleton();
s1.print();
}
程序编译的时候会报错。
探讨解决办法
既然我们不能再外部去实例化一个对象,那么在类内部实例化呢。
class Singleton{
Singleton singleton = new Singleton();
private Singleton(){
}
public void print(){
System.out.println("hello world");
}
}
程序编译通过。但是测试方法扔不可运行,也就是说此时是重点在于如何将内部的singleton对象传递到类的外部去。前面说过,由static标注的属性可以由类直接访问,那么上面的类改造一下:
class Singleton{
static Singleton singleton = new Singleton();
private Singleton(){
}
public void print(){
System.out.println("hello world");
}
}
@Test
public void test(){
Singleton s1 = null;
s1 = Singleton.singleton;
s1.print();
}
run result:
hello world
但是这样做本身也存在问题,因为我们知道类中的属性一般情况下需要封装。而属性封装之后,必须通过方法来获取属性,那么这个方法也必须声明为static方法。
问题解决
于是类将变成如下:
class Singleton{
private static Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleton;
}
public void print(){
System.out.println("hello world");
}
}
test:
@Test
public void test(){
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
Singleton s3 = Singleton.getInstance();
s1.print();
s2.print();
s3.print();
}
result:
hello world
hello world
hello world
因为所有的类共享static属性,虽然以上我们实例化了三个对象,但是他们都是指向同一个引用。也就是说不管外面如何使用,最终结果也只有一个实例化对象存在。这种模式在设计模式中被称为单例模式。