JavaSE第二十五讲:单例模式详解

public interface InterfaceTest{
	int a;
}
执行结果:

D:\src>javac InterfaceTest.java
InterfaceTest.java:2: 错误: 需要=
        int a;
             ^
1 个错误

【说明】:表示接口当中必须给其赋值。

public interface InterfaceTest{
	int a = 1;
}
编译通过

1. 接口中所声明的方法都是抽象方法。接口中的方法都是public的。

所以具体写法一般是这样:public static final int a = 1;但是通常情况下直接写为inta = 1;


2. 接口中也可以定义成员变量。接口中的成员变量都是 publicfinalstatic 的。【很少有情况在接口里面定义属性,一般是在接口中定义方法的】接口主要主要是起到一个约定的作用,主要是定义一个规则比如访问修饰符、返回类型等。


3. 一个类不能既是final,又是abstract的。因为abstract的主要目的是定义一种约定让子类去实现这种约定,而final表示该类不能被继承,这样abstract希望该类可以被继承而final明确说明该类不能被继承,两者矛盾。因此一个类不能既是final的,又是abstract的。

public abstract final class Test{
}
编译结果:

D:\src>javac Test.java
Test.java:1: 错误: 非法的修饰符组合: abstract和final
public abstract final class Test{
                      ^
1 个错误


4. Design Pattern(设计模式):设计模式不是一种技术,而是解决问题的方式,不局限于Java,任何面向对象语言都可以实现,而且大量依托于多态,设计模式一种思想,经典的设计模式有23种。

5.单例模式(Singleton):表示一个类只会生成唯一的一个对象。单即只有一个实例。

单例模式设计思路:

1)先根据单例模式的定义写以下程序再想思路。

public class SingletonTest{
	public static void main(String[] args){
	}
}

class Singleton{

}

2)一个类生成一个对象,new出一个实例的时候势必会调用一次构造方法。

3)如果提供了构造方法,并且用private修饰这个构造方法,则这个构造方法就只能在Singleton类里面访问,此时外面就不能new这个对象了

测试以下程序,验证用户在Singleton类外面不能new。

public class SingletonTest{
	public static void main(String[] args){
		Singleton singleton = new Singleton();
	}
}

class Singleton{
	private Singleton(){
	}
}

编译结果:
D:\src>javac SingletonTest.java
SingletonTest.java:3: 错误: Singleton()可以在Singleton中访问private
                Singleton singleton = new Singleton();
                                      ^
1 个错误

程序出现错误,所以可以把Singleton类里的构造函数用private修饰,通过这一点可以达到外部不能去访问Singleton类里的构造函数,从而达到不能new出Singleton的对象,此时距离只能new出一个实例接近了O(∩_∩)O~

4)对于private的构造方法,只能在内部访问,所以在类里面是可以new的,具体思路是在Singleton里面new出一个对象,然后再提供一个方法将这个对象想办法返回回来。然后在类的外部就不要new了就直接用提供的这个方法来接受返回回来的对象。

类似以下这个程序,当然只是作伪代码来分析。

public class SingletonTest{
	public static void main(String[] args){
		Singleton singleton = ...;
	}
}

class Singleton{
	private Singleton(){
	}

	public Singleton getInstance(){
		return ...;
	}
}

5)但是用下面这个程序执行的话,还是要new的,而之前定义的private的关系又导致不能new,所以此时应该换一种思路,将getInstance用static方法来修饰。这样外部就可以直接以类名.方法的形式调用了。

所以就有以下程序:

public class SingletonTest{
	public static void main(String[] args){
		Singleton singleton = Singleton.getInstance();
	}
}

class Singleton{
	private Singleton(){
	}

	public static Singleton getInstance(){
		return new Singleton();
	}
}
但是这种写法还不行,因为每次调用getInstance()都返回一个new出来的对象,这就不满足单例的需求。所以继续修改,我们可以先生成一个对象,然后调用一次就返回这个生成好的对象。

所以就有以下程序

public class SingletonTest{
	public static void main(String[] args){
		Singleton singleton = Singleton.getInstance();
	}
}

class Singleton{
	private Singleton singleton = new Singleton();
	private Singleton(){
	}

	public static Singleton getInstance(){
		return singleton;
	}
}
在Singleton类里面,new一个对象,调用私有构造方法,返回一个实例给singleton,然后再方法getInstanc()里面返回这个实例,但是这个程序是没办法编译过的,因为getSingleton()方法是静态的,静态方法不能访问非静态方法,所以将private Singleton singleton = new Singleton();改为private static Singleton singleton = new Singleton();

程序如下:

public class SingletonTest{
	public static void main(String[] args){
		Singleton singleton = Singleton.getInstance();
	}
}

class Singleton{
	private static Singleton singleton = new Singleton();
	private Singleton(){
	}

	public static Singleton getInstance(){
		return singleton;
	}
}

此时,此时单例模式设计完成,但是还是看不出来是否这个程序是单例模式,所以我们可以生成两个实例,然后验证这两个实例是否是相同,如果相同则输出true,所以完整的程序如下所示


public class SingletonTest{  
    public static void main(String[] args){  
        Singleton singleton = Singleton.getInstance();  
        Singleton singleton2 = Singleton.getInstance();  
        System.out.println(singleton == singleton2);  
    }  
}  
  
class Singleton{  
    private static Singleton singleton = new Singleton();  
    private Singleton(){  
    }  
  
    public static Singleton getInstance(){  
        return singleton;  
    }  
}

编译执行结果:
D:\src>java SingletonTest
true

【说明】:如果这个实例singleton和singleton2是同一个实例,则这两个实例指向同一个对象则他们地址相同,所以输出为true。


第二种实现方式

public class SingletonTest{
	public static void main(String[] args){
		Singleton singleton = Singleton.getInstance();
		Singleton singleton2 = Singleton.getInstance();
		System.out.println(singleton == singleton2);
	}
}

class Singleton{
	private static Singleton singleton;
	private Singleton(){
	}

	public static Singleton getInstance(){
		if(singleton == null){
			singleton = new Singleton();
		}

		return singleton;
		
	}
}

执行结果:
D:\src>java SingletonTest
true

【说明】:这个程序是在getInstance()里面加一个判断,如果还没有生成实例,则new出一个实例,如果已经生成实例,就是不为空的时候,则返回这个实例。


这两种方式实现结果一样,但是在多线程环境中,第一种方式效果会好,以为第二种实现方式在多线程环境中可能会产生一些差异。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值