参数化类的java单例

时间:2011-02-22 17:50:37

标签: java singleton design-patterns parameterized

我无法解开这个。

public class MySingleton<T extends AUsefulClass>{
    Map<String, T> myUsefulRegistry;
    private static MySingleton<T> _instance = null;

    public static instance(){
        if(instance == null)
            _instance = new MySingleton<T>();

        return _instance;
    }
}

public class Test{
    @Test
    public void testThis(){
        MySingleton<SomeClass> mySingleton = MySingleton<SomeClass>().instance();
    }
}

这种参数化是错误的,因为你不能对非静态T进行静态引用。但是,我想构建一个可参数化的单例类。

3 个答案:

答案 0 :(得分:4)

问题在于,在Java中(与.NET不同),无论您提供多少种不同的类型参数,您都只有一个静态变量 - 因此MySingleton<Foo>._instance等于MySingleton<Bar>._instance

我怀疑你想要一个Map<Class<? extends AUsefulClass>, MySingleton>,抑制有关原始类型的警告。然后,您也可以使instance方法获取Class<T>参数,这样它就会知道要查找的内容。

当然,这假设你想要不同类型参数的单独状态。如果您需要MySingleton<Foo>MySingleton<Bar>的不同状态,那么您可以真正拥有一个实例,并在抑制未经检查的转换警告的同时进行投射。

答案 1 :(得分:0)

这是一个解决方案:

public class MySingleton {
    private static MySingleton instance;

    private final Map<String, ?> myUsefulRegistry;

    private <T> MySingleton(Class<T> type) {
        myUsefulRegistry = new HashMap<String, T>();
    }

    public static <T> MySingleton getInstance(Class<T> type) {
        if (instance == null) {
            instance = new MySingleton(type);
        }
        return instance;
    }
}

如果您打算重新分配myUsefulRegistry,您显然必须省略 final 修饰符,并根据type参数实现状态(通过存储使用它)再次)。

编辑:如果用户将其他类型传递给原始文件,则会出现问题。您可能希望在任何情况下都存储该类型,因此您可以检查对getInstance(Class<T>)的任何正在进行的调用是否有效。

答案 2 :(得分:0)

在这种情况下,我宁愿看看我的设计。此外,如果您想创建一个不同的单身因素。您可能最初使用工厂来实例化单例。

我不确定单例模式是否是一种好方法,它通过对象引入全局状态,这是你可能不想要的东西。