2017-08-04 4 views
0

のみ2クラスリテラルの変数を使用することができbeeingている間、どのように以下を達成することが可能であるならば、私は、疑問に思うだろう:制限...既存の2つのクラスリテラルからパラメータ化されたクラスリテラルを構築する方法は?

Class<Foo<Bar>> getFoobar(){ 

    Class<Foo> fooClass = Foo.class; 
    Class<Bar> barClass = Bar.class; 

    // ... combine and return Class<Foo<Bar>> 
} 

を、それが不可能であることを、文字通り型を使用しますが、クラスリテラル変数から型をプログラムで取り出すことは可能です。

+1

私はあなたが正しく理解していれば、実際には存在しないタイプを返そうとしているので、これは可能ではないとは思わない...タイプのクラスはありません>動的に束縛される。しかし100%確かではありません。 –

+2

...明確にするために、ジェネリック型が 'Bar'のクラス' Foo'を持っていると仮定しています。 'Foo'と' Bar'のそれぞれの型を含む 'Class'の後ろにいますか? –

+0

@JSmithはい、そうです。 –

答えて

1

型パラメータを文字通り正しく使用することはできません。つまり、T.classまたはnew T()などの表現は動作しません。なぜなら、「プログラムによって」ジェネリック型をあまり扱うことができないからです。すなわち

foostr.getClass() == foobar.getClass() == Foo.class 

その結果、クラスリテラルを許可するにはポイントがありません、

Foo<String> foostr...; 
Foo<Bar> foobar...; 

我々は同じClassオブジェクトを持っています:パラメータ化のタイプは、このようにFoo<T>タイプの次のインスタンスのために、コンパイル後に自分の型パラメータを失いますFoo<String>.classまたはFoo<Bar>.classなどです。

これは、コンパイルタイプでのジェネリックタイプの多くの制限の背後にある理由です。実行時にタイプ引数についての情報がないため(イレーズタイプ)、コンパイル時に多くの可能性を制限する必要があります。

一つの可能​​性クラスFooParameterizedTypeとオブジェクトとしての型引数Bar、例えば情報を抽出され、実行時にジェネリック型で動作します

class Bar { 
    ... 
} 

class Foo<T> { 
    ... 
} 

class Foobar extends Foo<Bar> { 

    ParameterizedType getFoobar() { 
    return (ParameterizedType)getClass().getGenericSuperclass(); 
    } 
} 

... 

Foobar foobar = new Foobar(); 
System.out.println(foobar.getFoobar().getRawType()); // Foo.class 
System.out.println(foobar.getFoobar().getActualTypeArguments()[0]); // Bar.class 

別のアプローチ最初のものに基づいていますが、実装が簡単ですは、パラメータ化タイプをキャプチャするFasterXML Jacsonプロジェクトから(または独自のクラスを作成します)TypeReferenceの使用であります

class Foo<T> { ... } 

class Bar { ... } 

TypeReference typeReference = new TypeReference<Foo<Bar>>() {}; 
ParameterizedTypeImpl parametrizedType = (ParameterizedTypeImpl) typeReference.getType(); 
System.out.println(parametrizedType.getTypeName()); // Foo<Bar> 
System.out.println(parametrizedType.getRawType()); // Foo 
System.out.println(parametrizedType.getActualTypeArguments()[0]); // Bar 

詳細についてはParameterizedTypeImpl#toString()メソッドの実装をご覧ください。

関連する問題