Effective Java笔记第一章创建和销毁对象第三节用私有构造器或者枚举类型强化Singleton属性

Effective Java笔记第一章创建和销毁对象

第三节用私有构造器或者枚举类型强化Singleton属性

1.Singleton指仅仅被实例化一次的类。使类成为Singleton会使他的客户端测试变得十分困难。Java1.5之前,实现Singleton有两种方法,这两种方法都要把构造器保持为私有的,并导出公有的静态成员变量,以便允许客户端能访问该类的唯一实例。

2.公有静态成员是个final域

public class Demo1 {
    //公有静态成员final域
    public static final Demo1 INSTANCE = new Demo1();
    //私有构造防止实例化
    private Demo1() {
    }

    public void leaveTheBuilding(){

    }

    public static void main(String[] args) {
        Demo1 demo1 = Demo1.INSTANCE;
        System.out.println(demo1);
        Demo1 demo2 = Demo1.INSTANCE;
        System.out.println(demo2);
    }

优点:
1)私有构造器仅被调用一次,由于缺少公有的或者受保护的构造器,所以保证了类的全局唯一性。
2)公有域方法的主要好处在于,组成类的成员的声明很清楚地表明了这个类是个Singleton,公有的静态域是final的,所以该域将总是包含相同的对象引用。
缺点:
享有特权的客户端可以借助AccessibleObject.setAccessible方法,通过反射机制调用私有构造器。如果要抵御这种攻击,可以修改构造器,让他在被要求创建第二个实例的时候抛出异常。

3.公有的成员是个静态工厂方法

public class Demo2 {
    //公有静态成员final域
    private static final Demo2 INSTANCE=new Demo2();
    //私有构造防止实例化
    private Demo2(){

    }
    //静态工厂获取对象
    public static Demo2 getInstance(){
        return INSTANCE;
    }

    public void leaveTheBuilding(){

    }

    public static void main(String[] args) {
        Demo2 demo2 = Demo2.getInstance();
        System.out.println(demo2);
        Demo2 demo21 = Demo2.getInstance();
        System.out.println(demo21);
    }

}

工厂方法的优势:
1)提供了灵活性,在不改变其API的前提下,我们可以改变该类是否应该为Singleton的想法。
2)优势与泛型有关。
3)public域的方法比较简单。
缺点:
容易被修改,比如改成为每个调用该方法的线程返回一个唯一实例。

4.包含单个元素的枚举类型

public enum  Demo3 {
    INSTANCE;
    public void leaveThebuilding(){}

    public static void main(String[] args) {
        Demo3 demo3 = Demo3.INSTANCE;
        System.out.println(demo3);
        Demo3 demo31 = Demo3.INSTANCE;
        System.out.println(demo31);
    }
}

优势:
1)与共有域方法相近,更加简洁,无偿提供了序列化机制,绝对防止多次实例化,虽然还没推广,但单元素的枚举类型已经成为实现Singleton的最佳方法。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值