什么是单例模式?
采用一定的方法保证系统中,一个类的实例对象只能存在一个,并且只能使用该类中提供的一个取得对象实例的方法。
单例模式实现的两种方法
饿汉式
1. 将构造方法进行私有化
2. 内部类进行实例化
3. 提供一个公共的静态方法用于返回对象
package com.bj287.self_taught.singleT;
/**
* 作者: Juran on 2022-03-14 13:21
* 作者博客:iit.la
*/
public class SinGleT {
public static void main(String[] args) {
GirlFriend girlFriend = GirlFriend.getInstance();
System.out.println(girlFriend);
//打印输出结果 GirlFriend{name='hh'}
GirlFriend girlFriend1 = GirlFriend.getInstance();
System.out.println(girlFriend1 );
//打印输出结果 GirlFriend{name='hh'}
//创建两个对象并不会影响我们输出的结果,这里应该在使用GirlFriend类中加载时被static修饰的成员属性已经随着类的加载而执行,且只会执行一次。所以最后我们得到的结果一致。
}
}
class GirlFriend{
/**
* 单例模式:饿汉式
*1. 构造方法私有化
*2. 进行内部类对象创建
*3. 提供一个静态方法返回对象
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 构造器私有化
* @param name
*/
private GirlFriend(String name) {
this.name = name;
}
/**
* 内部类创建对象
*/
private static GirlFriend girlFriend = new GirlFriend("hh");
/**
* 创建公共静态方法返回对象
*/
public static GirlFriend getInstance(){
return girlFriend;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
那为什么又会被称作为饿汉式呢?我们我们可以在类中再加入一个属性进行调用,我们在进行调用这个属性的同时,这个类已经进行了实例化,不管我们用或者不能用到他他都会进行创建,所以着也就单例模式中的——饿汉式。
饿汉式可能会造成的结果:资源浪费。
懒汉式
1. 将构造方法进行私有化
2. 定义一个static静态属性对象。
3. 提供一个公共的静态方法用于创建对象。
public class SinGleT {
public static void main(String[] args) {
BoyFriend instance = BoyFriend.getInstance();
System.out.println(instance);
//第一次调用输出BoyFriend{name='Jack'}
BoyFriend instance1 = BoyFriend.getInstance();
System.out.println(instance1 );
//第二次调用因为我们我们已经将对象创建并赋值给了静态属,所以在getInstance方法中我们会直接将对象返回。
//所以最后一次打印的结果也是BoyFriend{name='Jack'}
}
}
class BoyFriend{
/**
* 懒汉模式
* 1.将构造方法进行私有化
* 2.定义一个static静态属性对象。
* 3.提供一个静态方法用于创建对象。
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造方法私有化
private BoyFriend(String name) {
this.name = name;
System.out.println("创建男朋友成功!" + name);
}
//定义一个static静态属性对象
private static BoyFriend boyFriend;
//提供方法用于进行对象的实例化
public static BoyFriend getInstance(){
if (boyFriend == null){
boyFriend = new BoyFriend("Jack");
}
return boyFriend;
}
@Override
public String toString() {
return "BoyFriend{" +
"name='" + name + '\'' +
'}';
}
那为什么又会被称作为懒汉式?在使用该类属性的同时并不会生成实例化对象,需要我们手动调用方法时,才返回对象,下次再次返回时会返回上一次已经创建的对象。
饿汉式 Vs 懒汉式
1.主要区别于两者创建对象的时机不同,饿汉式类加载时就已经将对象进行创建,而懒汉式是在使用时才进行类的创建。
2.饿汉式不存在线程安全,懒汉式存在线程安全问题。
3.饿汉式存在浪费资源的可能,创建了实例但是没有进行实例的使用,那么饿汉式就会存在浪费资源的情况,懒汉式是使用时才进行创建,就不会存在这种问题。
Java.lang.runtime就是经典的单例模式。