文章目录
一、简单的单例模式要点
1、某个只能有一个对象
2、必须自行创建这个实例
3、必须向整个系统提供这个实例
二、实现步骤(详细)
1、创建一个简单的构造函数
代码如下(创建一个构造函数):
public class SingleInstance {
public SingleInstance() {
System.out.println("我是一个构造函数");
}
}
代码如下(测试):
public class Test01 {
public static void main(String[] args) {
SingleInstance singleInstance1 = new SingleInstance();
}
}
代码如下(运行结果):
我是一个构造函数片
2、构造函数私有化
代码如下(改变构造函数的修饰词):
public class SingleInstance {
private SingleInstance() {
System.out.println("我是一个构造函数");
}
}
代码如下(测试是报错的):
public class Test01 {
public static void main(String[] args) {
SingleInstance singleInstance1 = new SingleInstance();
}
}
小结
由private修饰的构造函数在测试中是不能初始化的,所以只能再想办法
3、通过一个公有的方法提供访问
public class SingleInstance {
private SingleInstance() {
System.out.println("我是一个构造函数");
}
public static SingleInstance getSingleInstance() {
return singleInstance;
}
}
小结
由于构造函数是由private修饰的所以只能采取提供方法来访问,目前优先想到的是由static一起修饰的方法,访问格式是:类名.方法名 但是static修饰有自己的局限性,所以想要达到预期效果同步效果,成员变量也得是static来修饰,否则方法加载成功但是成员变量还没有加载,就会出现报错。
4、创建一个成员变量
public class SingleInstance {
private static SingleInstance singleInstance=new SingleInstance();
private SingleInstance() {
System.out.println("我是一个构造函数");
}
public static SingleInstance getSingleInstance() {
return singleInstance;
}
}
代码如下(测试):
public class Test01 {
public static void main(String[] args) {
SingleInstance singleInstance = SingleInstance.getSingleInstance();
System.out.println(singleInstance);
SingleInstance singleInstance1 = SingleInstance.getSingleInstance();
System.out.println(singleInstance1);
}
}
小结
我们总算得到了自己想要看到的结果,但是还是有不足那就是static修饰的通病就是如果加载进去用不到那就是占资源,所以为了解决这一毛病,我们可以在成员变量直接将初始化赋予null ,在提供访问的方法这里进行一个判断如果需要访问了就会进行判断,开始进行初始化,不需要则就不初始化,占资源的问题就迎刃而解了!!!
5、简单单例函数优化(赖汉式)
代码如下(优化):
public class SingleInstance {
private static SingleInstance singleInstance=null;
private SingleInstance() {
System.out.println("我是一个构造函数");
}
public static SingleInstance getSingleInstance() {
if(singleInstance == null) {
singleInstance = new SingleInstance();
}
return singleInstance;
}
}
代码如下(测试):
public class Test01 {
public static void main(String[] args) {
SingleInstance singleInstance1 = SingleInstance.getSingleInstance();
System.out.println(singleInstance1);
SingleInstance singleInstance2 = SingleInstance.getSingleInstance();
System.out.println(singleInstance2);
SingleInstance singleInstance3 = SingleInstance.getSingleInstance();
System.out.println(singleInstance3);
}
}
代码如下(测试结果):
我是一个构造函数
com.etime03.SingleInstance@70dea4e
com.etime03.SingleInstance@70dea4e
com.etime03.SingleInstance@70dea4e
6、简单单例函数(饥汉式)
其实就是在懒汉式的成员变量哪里改了一下再加一个final修饰,判断不需要了,其他的都一样的。
public class SingleInstance {
private static final SingleInstance singleInstance=new SingleInstance();
private SingleInstance() {
System.out.println("我是一个构造函数");
}
public static SingleInstance getSingleInstance() {
return singleInstance;
}
}
三、总结
其实每一行代码都有它的作用,每一个属性都有它存在的意义,就像人生上的细胞,虽然微小,但是它是构成你一个整体的一部分,所以代码虽少但是理解为上,每个东西都不会平白无故的出现,也不会平白无故的消失,就由我上面的代码那个SingleInstance是由static修饰的一样,其实它可以不用static修饰的,但是下面提供访问函数就会报错,因为没有一起加载进来,所以就会报找不到的错误,那你可能会问那访问方式不用static修饰不就好了,那你就片面了,private修饰私有化就没有意义了,一切回到起点,你的属性安全就没有保障,成为任人宰割的羔羊,就可以随意改你的东西,单列模式就没有任何实现的可能,所以,都是一环扣一环的,在学Java这条路上任重而道远啊!刚学到继承,大佬勿喷。