クラスで、コンストラクターの 1 つが空のジェネリック型util.TreeSet
を持つ新しいコンストラクターを呼び出していることがわかりました。TreeMap
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
とはnew TreeMap<>
どういう意味ですか? と同等new TreeMap<?>
ですか?
This is Java 7 syntax. The diamond (<>
) is a short-hand to ask the Java compiler to fill generic arguments with whatever makes sense in the local context (in this case, it'll be ? super E
).
いいえ 、<?>
と <>
は同じではありません。
<?>
は「無制限のワイルドカード」であり、Java 5 以降存在しています。このワイルドカードは、タイプ バウンドが許可するすべてのものを許可 (つまり一致) し、追加の制限はありません。ワイルドカードを使用すると、ジェネリック インスタンスで実行できる操作が犠牲になります。wildcards の詳細については、Java チュートリアルのセクションを参照してください。どのタイプの境界でどのワイルドカードが許可されているかについては、このブログを参照してください。
"<>"
Java 7 では、ひし形演算子である が追加されました。その目的は、コンストラクターを呼び出すときにコンパイラーがコンテキストからそれらの型を推測するようにすることで、ジェネリック型のインスタンスを作成するときに開発者が不必要に冗長になるのを防ぐことでした。
コンパイラは、可能な限り最も具体的な型を推測し、利用可能な場合は以下を考慮します。
1- コンストラクターに渡される引数の型。
2- 新しいインスタンスが割り当てられる参照で指定する型 (「=」割り当ての左側部分)。
3- タイプの消去。
あなたの例では、コンパイラnew TreeMap<>(comparator)
はnew TreeMap<E,Object>(comparator)
.
その理由を理解するために、TreeMap<K,V>
呼び出されているコンストラクターを見てくださいTreeMap(Comparator<? super K> comparator)
。
コンパイラは と の型を推測する必要がK
ありV
ます。a が期待され、 a が に渡されていることがComparator<? super K>
わかり、Comparator<? super E>
左側の代入はなく、コンパイラはへの代入に問題はありませんE
( K
anE
に一致するものはすべて、同じ消去があるため a に一致します)、 =K
と結論付けます。K
E
の場合V
も、左側の代入はなく、コンストラクタに渡されるパラメータもないため、with erases toでV
指定された型の消去が残されているため、 =と結論付けます。TreeMap<K,V>
Object
V
Object
これで、コンパイラはK
=E
とV
=Object
を推論し、ステートメントは になりTreeMap<E,Object>(comparator)
ます。
コンストラクターはジェネリック型変数で定義できるため、ひし形演算子は作成されるインスタンスのジェネリック型を推測しますが、コンストラクターがジェネリックである場合に呼び出されるコンストラクターのジェネリック型を推測しません。ジェネリック メソッドを定義するのと同じように (クラスで定義されていない追加の型を追加する場合)、これらの型も、ダイヤモンド演算子ではなく、ジェネリック メソッドの型を推論する方法と同様に、コンパイラによる推論の対象となります。