java Singleton - 通过反射防止多次创建 [英] java Singleton - prevent multiple creation through reflection

查看:203
本文介绍了java Singleton - 通过反射防止多次创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的单身。

I have a singleton like this.

public class BookingFactory {

    private final static BookingFactory instance;

    static {
        instance = new BookingFactory();
    }

    public static BookingFactory getInstance() {
        return instance;
    }

    private BookingFactory() {
        System.out.println("Object is created.");
    }
}

public class Test  {
    BookingFactory instance = BookingFactory.getInstance();
    instance = BookingFactory.getInstance();

    Class<?> clazz = Class.forName("com.test.BookingFactory");

    Constructor pvtConstructor = clazz.getDeclaredConstructors()[0];

    // Set its access control
    pvtConstructor.setAccessible(true);

    // Invoke Private Constructor
    BookingFactory notSingleton = (BookingFactory) pvtConstructor.newInstance(null);
}

当我运行这个时,我看到了多条打印输出消息。有没有办法阻止这个单例从这个反射中被多次实例化?

When I run this, I saw more than one printout message. Is there any way to prevent this singleton from being instantiated more than once from this reflection?

谢谢。

推荐答案

尝试使用枚举。 enums for good Singletons。

Try using an enum. enums make for good Singletons.

public static enum BookingFactory {
    INSTANCE;
    public static BookingFactory getInstance() {
        return INSTANCE;
    }
}

您无法通过反射创建枚举。

You can't create an enum via reflection.

getInstance()方法是多余的,但可以更容易地运行测试,抛出以下异常:

The getInstance() method is superfluous but makes it easier to run your test, throwing the following exception:

java.lang.IllegalArgumentException: Cannot reflectively create enum objects
    at java.lang.reflect.Constructor.newInstance(Constructor.java:530)
    at MultiSingletonTest.main(MultiSingletonTest.java:40)

哦,看,有人已经给出了枚举答案。无论如何都要张贴更完整。

Oh look, someone already gave the enum answer. Posting anyway for more completeness.

这篇关于java Singleton - 通过反射防止多次创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆