2017-02-06 3 views
0

Я не очень хорошо знаю Java, поэтому хотел бы спросить, реализована ли эта реализация. (Безопасность резьбы не имеет значения). Я хочу, чтобы для каждого класса T был выбран единственный уникальный синглтон.Один синглтон для каждого (общего типа)

public class MockDatabase<T> { 
    private MockDatabase() {} 

    private static Map<String, MockDatabase> singletonHolder = new HashMap<String, MockDatabase>(); 

    public static <T> MockDatabase<T> getInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException { 
     MockDatabase<T> singleton = (MockDatabase<T>)singletonHolder.get(clazz.getName()); 
     if (singleton == null) { 
      singleton = new MockDatabase<T>(); 
      singletonHolder.put(clazz.getName(), singleton); 
     } 

     return singleton; 
    } 
} 
+1

Почему вы используете ключ 'clazz.getName()', а не 'clazz'? –

+0

Вы не должны использовать необработанные типы ('Map ' использует raw 'MockDatabase'). Кроме того, вы не должны использовать одну и ту же букву типа для параметра класса 'T' и общий параметр метода' ', поскольку это создает иллюзию того, что они одного типа. – RealSkeptic

+1

Почему вы не добавляете в кеш одиночный экземпляр, который вы создаете, когда у держателя нет? – davidxxx

ответ

1

Простое решение, которое также поточно является использование ClassValue

public class MockDatabase<T> { 
    private static final ClassValue<MockDatabase> cache = new ClassValue<>() { 
     protected MockDatabase computerValue(Class<?> clazz) { 
      return new MockDatabase(); 
     } 
    } 
    public static <T> MockDatabase<T> getInstance(Class<T> clazz) { 
     return (MockDatabase<T>) cache.get(clazz); 
    } 
} 

Cl assValue вернет тот же объект значения для любого класса и будет потокобезопасным.

Примечание: ClassValue очищается, когда класс больше не ссылается.

+0

Это выглядит намного чище! – EralpB

+0

@ EralpB, некоторые разработчики Java знают об этом классе, даже если он находится в java.lang –

1
if (singleton == null) { 
     singleton = new MockDatabase<T>(); 
} 

Изменение выше кода

if (singleton == null) { 
     singleton = new MockDatabase<T>(); 
     singletonHolder.put(clazz.getName(),singleton); 
} 

Другой мудрый вы получите новый объект каждый раз, когда

+0

Это правда, спасибо, что указали! – EralpB

Смежные вопросы