2017-01-23 8 views
0

動的な型を返す:別のクラスでJavaのジェネリックあなたがこれを持っているような状況を想像し

// Marker 
interface Type {} 

interface CustomType extends Type { 
    int getSomething(); 
    int getAnotherThing(); 
} 

class CustomTypeImpl implements CustomType { 
    public int getSomething() { 
     return 1; 
    } 
    public int getAnotherThing() { 
     return 2; 
    } 
} 

を、私はこのような一般的なメソッドを持つようにしたい:の実装を返す

public <T extends CustomType> T getFromInterface(Class<T> clazz) 

クラスIをパラメータに入れます。たとえば、このメソッドを以下のように呼び出すとします。SomeInstanceOfClass.getFromInterface(CustomType.class)そしてCustomTypeImplのインスタンスを返します。

@EDIT:私はgetFromInterface(Class<T> clazz)メソッドの引数として使用できるすべてのインターフェイスを格納するメソッドにアクセスできることを言いました。

このメソッドのシグネチャは、次のとおりです。public Set<? extends Class<? extends Type>> allTypes()

は、どのように私はこれをしてください行うために管理することができますか?

+0

インターフェイスに2つの実装がある場合はどうなりますか?それが決してしなければ、とにかくインターフェイスのポイントは何ですか? –

+0

実際には、オブジェクトに共通のタイプを持つことを可能にするマーカーインターフェイスがあります。状況は次のようなものです:interface Type {// marker} interface CustomTypeはType {// look above}と私の実装を拡張します。実際には、Typeを拡張する他のインターフェイスがあり、Typeを拡張する各インターフェイスの実装があります。 –

+3

答えがあなたの質問を解決するかもしれませんが、あなたの問題が何であれ、おそらくもっと良い解決策があると思います。 –

答えて

2

リフレクションを使用して、クラスオブジェクトで新しいインスタンスを作成できます。どのクラスが何らかのインタフェースを実装しているかについての情報は、いくつかのマップに格納できます。

private static final Map<Class<?>, Class<?>> interfaceToImplementationMap = new HashMap<Class<?>, Class<?>>() {{ 
    put(CustomType.class, CustomTypeImpl.class); 
}}; 

public static void main(String[] args) throws InstantiationException, IllegalAccessException { 
    CustomType instance = getFromInterface(CustomType.class); 
    System.out.println(instance); 
} 

public static <T> T getFromInterface(Class<T> clazz) throws IllegalAccessException, InstantiationException { 
    return clazz.cast(interfaceToImplementationMap.get(clazz).newInstance()); 
} 
+1

「二重ブレース初期化」を決して使用しない理由を説明するWebページが多数あります。代わりに静的初期化ブロックを1つ使用してください。それ以外に、良い答え。 – VGR

+0

それは本当です。私は上記のコメントに絶対に同意します。また、com.google.common.collect.ImmutableMapとその静的メソッド - ビルダーをguavaライブラリから見てみることをお勧めします。 –

関連する問題