java - ジェネリックメソッドを明示的に呼び出す

java generics

インターフェースと実装がある場合:

interface BaseInterface{ }
class Base implements BaseInterface{ }


そしてどこかに私は方法があります:

<T extends Base> T foo() { /* return object of class T */ }


foo()は、インターフェースに割り当てるために、Baseで明示的に呼び出す必要があります。これはうまく動作します:

BaseInterface a = <Base>foo();


結構です...しかし、どうすれば次のメソッドを明示的に呼び出すことができますか?

<V extends Base> Map<String, V> bar() { /* return object of Map<String, V> */ }


これらはどれも動作しないようです:

Map<String, ? extends BaseInterface> m = <Base>bar();
Map<String, ? extends BaseInterface> m = <String, Base>bar();
Map<String, ? extends BaseInterface> m = <Map<String, Base>>bar();
答え
ジェネリックの使い方を少し誤解していると思います。

あなたが今持っているのはこれです:

<T extends Base> T foo() {...}


これは、英語では、fooBaseのサブクラスであるオブジェクトを返すことを意味します(サブクラスは「このクラスまたは任意の子クラス」を意味することに注意してください)。しかし、fooは引数を取らないため、fooの実装がTのバインド先を知ることも、Tのバインド先も重要ではありません。すべてのfooが気にします。呼び出し元が気にするのは、なんらかのBaseを返すことだけです。

基本的に、あなたが持っているものはこれと同等です:

Base foo() {...}


この場合、ジェネリックを使用する必要はありません。これは、fooが型情報を気にする必要がないためです。Baseのサブクラスを返すだけです。これを行っていた場合は、次のように異なります。

<T extends Base> T doSomething(T input)


doSomethingは、戻り値の型を決定するためにジェネリック型情報を必要とするためです。

foobarをジェネリックとして宣言するのではなく、単に次のように宣言しないでください。

Base foo();
Map<String, Base> bar();


または、さらに良いことに、

BaseInterface foo();
Map<String, BaseInterface> bar();


これで、クライアントコードを記述できます。

BaseInterface a = foo();
Map<String, BaseInterface> m = bar();


私はこれがあなたの質問に直接答えないことを知っていますが、あなたの場合(サンプルコードを与えられた場合)、問題を解決するためにジェネリックを使う必要は本当にないと思います。ジェネリックスとポリモーフィズムを混同するのは簡単です。この場合、ポリモーフィズムはあなたの友人です。
関連記事

java - repaint()エラー。私の再描画メソッドは画面を点滅させるだけです

java - Androidでラテン語のアクセント付き文字を使用する方法

java - Androidレイアウトの遷移効果

java - JavaでWebサービスを介して複数のセッション要求を維持する

java - リソースをSDカードにコピーすると、Androidで破損したファイルが表示されます

java - JavaScriptのような構文を自分のJavaメソッドに解析する

java - IllegalArgumentException:オブジェクトの配列をSCHEMA_SOURCEプロパティの値として使用する場合、2つのスキーマが同じtargetNamespaceを共有することはできません

java - Notnoop / java-apnsプッシュ

java - iTextを使用してJSPでPDFファイルの限られた数のページを表示する方法は?

java - サーバー側のJax-rs呼び出しをプレフィックスのないネイティブファイルと混在させる方法は?