Java-синглтон параметризованного класса - PullRequest
2 голосов
/ 22 февраля 2011

Я не могу распутать это.

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 ]

4 голосов
/ 22 февраля 2011

Проблема в том, что в Java (в отличие от .NET) у вас есть только одна статическая переменная, независимо от того, сколько аргументов различных типов вы предоставляете - так что MySingleton<Foo>._instance равно MySingleton<Bar>._instance.

Я подозреваю, что вы хотите Map<Class<? extends AUsefulClass>, MySingleton>, подавляя предупреждения о необработанных типах. Тогда вы бы заставили свой метод instance принять параметр Class<T>, чтобы он знал, что искать.

Конечно, это предполагает, что вы хотите отдельное состояние для аргументов другого типа. Если вы не нуждаетесь в другом состоянии для MySingleton<Foo> и MySingleton<Bar>, вы действительно можете иметь один экземпляр и просто разыграть его, подавляя предупреждение о непроверенном преобразовании.

0 голосов
/ 22 февраля 2011

Я бы лучше посмотрел на мой дизайн в этом случае. Также, если вы хотите создать другой синглтон из-за обстоятельств. Сначала вы могли бы использовать фабрику для создания экземпляра синглтона.

Я не уверен, что шаблон синглтона является хорошим подходом, он вводит глобальное состояние через объекты, а это то, чего вы, вероятно, не хотите.

0 голосов
/ 22 февраля 2011

Вот решение:

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>).

...