2017-02-06 1 views
0

私はJavaをよく知らないので、この実装がOKかどうか質問したいと思います。 (スレッドセーフではありません)。私はTクラスごとに単一のユニークなシングルトンを望みます。各(ジェネリック)タイプのための1つのシングルトン

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'ではなく' clazz.getName() 'をキーしますか? –

+0

生の型を使うべきではありません( 'Map 'は生の 'MockDatabase'を使います)。また、クラスパラメータ 'T'とメソッド汎用パラメータ' 'に同じタイプの文字を使うべきではありません。これは、それらが同じ型であるという錯覚を作り出すからです。 – RealSkeptic

+1

所有者が所有していないときに作成するシングルトンインスタンスをキャッシュに入れないのはなぜですか? ...のpublic staticは MockDatabase のgetInstanceを(同期) – 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.langにあってもこのクラスについて知っているJava開発者はほとんどいません –

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

if (singleton == null) { 
     singleton = new MockDatabase<T>(); 
     singletonHolder.put(clazz.getName(),singleton); 
} 
に上記のコードを変更し

他の賢明なあなたは

+0

それを指摘していただきありがとうございます。 – EralpB

関連する問題