2

Java のこの静的関数では、なぜ<K, V>行 1 で繰り返さなければならないのでしょうか?

public static <K, V> HashMap<K, V> newInstance() {
  return new HashMap<K, V>();
} 

HashMap<K, V>関数はジェネリック型 K と V をそれぞれキーと値として持つ HashMap を返すため、必要な理由を理解しています。しかし、なぜ<K, V>関数の署名に最初が必要なのですか?

4

4 に答える 4

6

メソッドがジェネリック メソッドであることを示すため、ジェネリック型を使用する/返す。それらが存在しない場合、コンパイラは K という名前の具象型と V という名前の別の具象型を探します。

于 2012-06-23T22:04:53.473 に答える
1

関数newInstanceもジェネリックであるため、に転送されるジェネリック型KおよびVHashMapがあります。次のように使用することを意図しています。

HashMap<Integer, String> map = newInstance<Integer,String>();
于 2012-06-23T22:04:33.467 に答える
1

コンパイラは型パラメータを合理的に推測できますか?

はい、例の状況では -static HashMap<K,V>newInstance(){return new HashMap<>();}は明らかに の略ですstatic < K extends Object , V extends Object > HashMap<K,V>newInstance()return new HashMap<K,V>();}

ただし、コンパイラが型パラメーターを推論した場合、クラス名を誤って入力してもコードはコンパイルされます。 はおそらく間違っていますが、コンパイラは、ランタイム消去の魔法を通して、と同等であるstatic void setName ( Sting name )と想定します。<Sting extends Object> static void setName ( Sting name );static void setName ( Object name ) ;

メソッドが静的でない場合、推論が問題になります。 class X { HashMap<K,V>newInstance(){return new HashMap<>();}}次のいずれかとして型推論できます。

  1. class X <K extends Object , V extends Object> { HashMap<K,V>newInstance(){return new HashMap<>();}}
  2. class X <K extends Object > { < V extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
  3. class X <V extends Object> { < K extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
  4. class X { <K extends Object , V extends Object> HashMap<K,V>newInstance(){return new HashMap<>();}}

さらに、型パラメーターが推論された場合、その順序は何ですか。それらが明示的に述べられている場合、順序は明らかです。推論された型パラメーターの順序の問題を解決する唯一の (私には明らかな) 方法は、コードで宣言された順序です。ただし、コードの 2 行の順序を逆にすると (重要ではないはずです)、パブリック インターフェイスが変更され、ビルドが中断される可能性があります。とてももろい!

于 2012-06-23T22:28:43.260 に答える
1

他の回答に追加するには、消去すると、コンパイル時にすべての型が失われます。ただし、コンパイラは最初に検証をチェックするため、型が必要になります。

別の SO answerから消去した後に何が起こるかの例を次に示します。

ただし、ジェネリックを使用すると、コンパイル時のチェックと実行時のキャストに変換されます。したがって、このコード:

リスト リスト = 新しい ArrayList(); list.add("こんにちは"); 文字列 x = list.get(0);

にコンパイルされます

リスト リスト = 新しい ArrayList(); list.add("こんにちは"); 文字列 x = (文字列) list.get(0);

于 2012-06-23T22:10:49.377 に答える