单例模式------饿汉式/懒汉式

一.

(1). 饿汉式: 

public class Single {
    public static void main(String[] args) {
        //无法创建Girl对象,所以使用Girl类的类方法
        Girl girl1= Girl.getInstance();
        Girl girl2= Girl.getInstance();
        System.out.println(girl1);
        System.out.println(girl2);
        //一定返回true ,因为它们都是引用了Girl中的同一个对象
        System.out.println(girl1==girl2);

    }
}

class Girl
{
    private String name;

    //注意这是一个静态属性初始化, 所以在类加载的时候就被执行, 因此只要符合三种情况就可以被加载
    private static Girl t=new Girl("小红");

    //(1)将构造方法私有化
    //(2)在类的内部创建一个对象
    //(3)用一个static方法返回此对象
    private Girl(String name)
    {
        this.name=name;
    }

    public static Girl getInstance()
    {
        return t;
    }

    @Override
    public String toString() {
        return "Girl{" +
                "name='" + name + '\'' +
                '}';
    }
}

(2). 饿汉式可能会造成资源浪费,可能会发生创建了对象但没有使用的情况:

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

        //举例说明资源浪费:
        //此时只使用了n并没有想使用girl对象的意思,但是只要使用静态成员类就会被加载,会自动执行 private static Girl t=new Girl("小红");
        System.out.println(Girl.n);

    }
}

class Girl
{
    private String name;
    public static int n=1;  //静态属性
    //注意这是一个静态属性初始化, 所以在类加载的时候就被执行, 因此只要符合三种情况(因为创建不了对象,所以一般是调用静态成员时被调用)就可以被加载
    //所以会发生: 只要使用了类的其中一个静态成员,这个静态属性就会被加载,因此会造成浪费(举例说明)
    private static Girl t=new Girl("小红");

    //(1)将构造方法私有化
    //(2)在类的内部创建一个对象
    //(3)用一个static方法返回此对象
    private Girl(String name)
    {
        System.out.println("构造器被调用");
        this.name=name;
    }

    public static Girl getInstance()
    {
        return t;
    }

    @Override
    public String toString() {
        return "Girl{" +
                "name='" + name + '\'' +
                '}';
    }
}

二.

(1). 懒汉式: 

public class Single1 {
    public static void main(String[] args) {
        Cat cat1=Cat.getInstance();
        Cat cat2=Cat.getInstance();
        System.out.println(cat1);
        System.out.println(cat2);

        System.out.println(cat1==cat2);

    }
}
class Cat
{
    private String name;
    //区别就在于静态属性有没有初始化,饿汉式直接初始化所以类加载就会创建对象
    //而懒汉式是一个静态属性,没有静态属性初始化, 所以在类被加载的时候不会执行,也就不会出现调用其他静态成员时,会直接创建对象的饿汉式行为
    private static Cat cat;

    //(1)依旧是私有化构造方法
    //(2)在类的内部声明一个静态属性对象,而不是创建初始化
    //(3)提供一个public 的static方法,可以返回一个Cat对象
    private Cat(String name)
    {
        System.out.println("构造器被调用");
        this.name=name;
    }

    public static Cat getInstance()
    {
        if(cat==null)
        {
            cat=new Cat("小可爱");
        }
        //且创建一次后不为空,所以返回的一直是同一个对象
        return cat;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

(2). 懒汉式不会发生创建对象没有使用的情况 :

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

        //调用n是不会调用到构造方法的 ,因为懒汉式只是声明静态属性,而没有初始化静态属性
        System.out.println(Cat.n);

    }
}
class Cat
{
    private String name;
    
    public static int n=100;
    //区别就在于静态属性有没有初始化,饿汉式直接初始化所以类加载就会创建对象
    //而懒汉式是一个静态属性,没有静态属性初始化, 所以在类被加载的时候不会执行,也就不会出现调用其他静态成员时,会直接创建对象的饿汉式行为
    private static Cat cat;

    //(1)依旧是私有化构造方法
    //(2)在类的内部声明一个静态属性对象,而不是创建初始化
    //(3)提供一个public 的static方法,可以返回一个Cat对象
    private Cat(String name)
    {
        System.out.println("构造器被调用");
        this.name=name;
    }

    public static Cat getInstance()
    {
        if(cat==null)
        {
            cat=new Cat("小可爱");
        }
        //且创建一次后不为空,所以返回的一直是同一个对象
        return cat;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

 三. 区别

1. 主要区别: 创建对象的时机不同, 饿汉式在类加载的时候就创建了对象实例, 而懒汉式是在使用的时候才创建对象实例 .

2. 饿汉式不存在线程安全问题, 懒汉式存在线程安全问题.(多线程的时候判断条件会出现问题)

3.饿汉式存在浪费资源的可能, 懒汉式是在使用时才创建,所以没有这个问题.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值