02.用私有构造器或者枚举类型强化Singleton属性

本文探讨了四种实现Singleton模式的方法,包括使用公有静态final域、静态工厂方法、通过序列化控制实例数量以及利用单元素枚举。最后指出,枚举是单例的最佳选择,但需注意在扩展超类而非枚举时的适用性
摘要由CSDN通过智能技术生成

02.用私有构造器或者枚举类型强化Singleton属性

Singleton是指仅仅被实例化一次的类。实现Singleton有三种常见的方法:
1.公有静态成员为final域

/**
 * 类描述: Singleton with public final field
 */
public class Elvis {

    public static final Elvis INSTANC = new Elvis();

    private Elvis(){}
    

}

2.公有成员为静态工厂方法

public class Elvis {

    public static final Elvis INSTANC = new Elvis();

    private Elvis(){}

    public static Elvis getInstanc() {
        return INSTANC;
    }
    
}

3.实现序列化接口,控制反序列化创建假冒的实例

public class Elvis implements Serializable {

    public static final Elvis INSTANC = new Elvis();

    private Elvis(){}

    public static Elvis getInstanc() {
        return INSTANC;
    }

    private Object readResolve() {
        return INSTANC;
    }

}

public static void main(String[] args) {
        Elvis firstInstance = Elvis.INSTANC;
        String fileName = serializable(firstInstance);
        Elvis secondInstance = deSerializable(fileName);
        System.out.println(firstInstance == secondInstance);
    }
    static String serializable(Elvis firstInstance) {
        try {
            String fileName = "1.txt";
            FileOutputStream fos = new FileOutputStream(fileName);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(firstInstance);
            oos.close();
            return fileName;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
    static Elvis deSerializable(String fileName) {
        try (FileInputStream fileIn = new FileInputStream(fileName);
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            Object obj = in.readObject();
            return (Elvis) obj;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

4.声明一个包含单个元素的枚举类

public enum  Elvis {
    INSTANC;
}

public class Test2 {

    public static void main(String[] args) throws Exception{
        Elvis elvis = Elvis.INSTANC;
        Constructor<Elvis> constructor = Elvis.class.getDeclaredConstructor();
        constructor.setAccessible(true);
        Elvis reflectInstance = constructor.newInstance();
        System.out.println(elvis == reflectInstance);
    }

}

测试结果:
Exception in thread "main" java.lang.NoSuchMethodException: effective02.Elvis.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.getDeclaredConstructor(Class.java:2178)
	at effective02.Test2.main(Test2.java:16)

总结

单元素枚举类型经常成为Singleton最佳方法,注意,如果Singleton必须扩展一个超类,而不是扩展Enum的时候,
则不适用适用这个方法(虽然可以声明枚举去实现接口)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值