当我们在编写代码时,我们规定一个类中只能创建一个实例对象时,就像说老婆只能有一个这样的特殊情况时,这样我们就可以运用单例模式来创建对象,单例模式有俩种分明是懒汉式和饿汉式,当我们只能创建一个对象时,我们的构造器就要设置为private,让其他类不能访问该类的构造器,所以我们需要先在内部进行构造一个对象,再用一个public修饰的方法来接受创建的对象。下面懒汉式和饿汉式的俩个具体实例和一些必要的解释。
1.饿汉式
饿汉式我们可以理解为非常着急的一种方法,它是先创建好对象,但是用不用是根据你的需求来的。下面是实例代码:
//单例模式(饿汉式)
public class Course{
public static void main(String[] args) {
System.out.println(Wife.f1());
}
}
class Wife{
private String name;
private static Wife wife = new Wife("小红");
private Wife(String name) {
this.name = name;
}
public static Wife f1() {
return wife;
}
@Override
public String toString() {
return name;
}
}
在该代码中我们是无法通过创建实例对象来获取对象的,所以我们在代码中的f1()必须设置为public static因为静态方法是在类加载的时候创建所以不需要创建实例对象,因为获取wife的方法为静态方法所以Wife对象必须也为static否则f1()无法访问Wife对象,因为这里的toString()方法并没有重写,我们不重写toString方法的话我们打印出来的则是wife这个对象的地址,这里我们重写了方法让它返回一个name值。
2.懒汉式:
懒汉式顾名思义这个方法它很懒,它只有在调用时发现调用的对象为NUll时才会创建对象,下面时懒汉式的代码实例:
该方法和饿汉式有很多相似的地方,只是在调用方法时f1()调用对象的处理方式不一样,它只会在你主方法里调用f1()方法时它先看你的对象是否为Null,如果为Null的话才会创建一个对象。
//单例模式(懒汉式)
public class Course{
public static void main(String[] args) {
Wife wife3 = Wife.f1();
Wife wife2 = Wife.f1();
System.out.println(wife3 == wife2);
System.out.println(Wife.f1());
}
}
class Wife{
private String name;
private static Wife wife;
private Wife(String name) {
this.name = name;
}
public static Wife f1() {
if (wife == null){
wife = new Wife("小红");
}
return wife;
}
@Override
public String toString() {
return name;
}
}
但是懒汉式和饿汉式的f1()的方法可以被多次调用付给其他的对象但是其他对象所指向的地址肯定是同一个地址。
懒汉式和饿汉式的缺点:
懒汉式的缺点:
1.线程不安全。在多线程环境下,如果多个线程同时进入判断对象是否为null的条件,可能会导致创建多个实例,违背了单例的原则。
2.性能较低。由于需要在每次获取实例时进行判断和同步控制,可能会导致性能下降。
饿汉式的缺点:
1.类加载时就创建实例。在程序加载时就创建实例,无论后续是否会使用该实例,都会占用一定的内存空间。如果单例实例比较庞大或者创建实例需要进行复杂的初始化操作,可能会导致性能问题或资源浪费。
2.无法延迟加载。无论是否需要使用该实例,都会在类加载时创建实例,无法根据需要进行延迟加载。如果该实例在程序执行期间很少被使用,可能会造成不必要的开销。
综上:懒汉式的主要缺点是线程不安全和性能较低,需要在代码中增加额外的同步控制。而饿汉式的主要缺点是无法延迟加载和占用一定的内存空间,缺点的解决放在后面的线程中来实施解决。