【Java20】单例类

类成员

使用static修饰的成员就是类成员。

一个类内,可以有5种成员:成员变量、成员方法、构造器、初始化块、内部类(包括接口和枚举)。除了构造器,其他都可以用static修饰。

类变量(外部声明的叫变量)属于整个类而不是某一个对象。系统第一次使用这个类的时候,系统会为该类变量分配内存空间,类变量开始生效,直到该类被卸载,类变量所占空间才会被垃圾回收机制回收。类初始化完成时,类变量也被初始化完成。

类变量既可以通过类来访问,也可以通过对象来访问。但后者只是Java允许的,是一种假象,实际上访问的还是类变量。

与类变量类似,类方法也是既可以通过类,也可以通过对象来调用。但实际上还是类调用。

对象访问类成员,实际上是在底层转换为类来访问。一个最极端的证明方式是:即使一个类的实例是null,也可以访问类成员:

public class NullAccessStatic
{
  private static void test()
  {
    System.out.println("类方法");
  }
  public static void main(String[] args)
  {
    NullAccessStatic nas = null; // 初始化为null的引用变量
    // 依然可以访问类成员、调用类方法
    nas.test();
  }
    
}
单例类

一个类,如果构造器是public的,那么外部可以创建无数个该类的实例(对象)。

但如果不太像反复创建实例,比如房子里只有一个茶几、游戏只有一个窗口,这时反复创建多个对象就没有太大的实际意义。

如果一个类始终只能创建一个实例,这种类就称为单例(Singleton)类。

Q1: 如何确保不能自由创建实例呢?

A1: 把构造器修饰为private,隐藏起来。

Q2: 隐藏起来以后,又该如何去创建这个类的对象呢?

A2: 提供另一个public的方法,在这个方法里创建该类的对象。

Q3: 在调用这个方法之前,对象还不存在呢,该咋整?

A3: 使用static修饰,让它变成类方法。直接通过类来调用。

Q4: 如何确保这个方法只创建了一个对象?

A4: 用一个成员变量来保存曾经创建的对象。因为该成员变量需要被上面的类方法访问,故该成员变量也要用static修饰。

class Singleton
{
    // 使用一个类变量来缓存曾经创建的实例
    private static Singleton instance;
    // 隐藏构造器
    private Singleton(){}
    // 提供一个public方法,能够返回Singleton实例
    // 且同时确保只产生一个Singleton实例
    public static Singleton getInstantce()
    {
        // 如果instance为null,说明还未创建实例
        // 否则说明已经创建了实例
        if (instance == null)
        {
            // 在类内调用private构造器没有问题
            instance = new Singleton(); // 创建一个实例
        }
        return instance;
    }
}

public class Test
{
    public static void main(String[] args)
    {
        // 通过构造器创建Singleton实例是不可能的
        // 只能通过提供的getInstance方法来“获得”这个实例
        var s1 = Singleton.getInstantce();
        var s2 = Singleton.getInstantce();
        // 这两个引用变量指向的是同一个对象
        System.out.println(s1 == s2); // 输出true
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值