また、この質問は理解しにくいと思います。1つのコマンドを2つのコマンドに分割することは私を助けました。
以下のコードは、元のメソッドが検査およびコンパイルされたときにバックグラウンドで実際に発生することです。コンパイラーは独自のローカル変数を作成します。i.get(0)
呼び出しの結果は、ローカル変数スタックのレジスターに配置されます。
これは、この問題を理解するために、便宜上名前を付けたローカル変数を作成するのと同じelement
です。
import java.util.List;
public class WildcardError {
void foo(List<?> i) {
Object element = i.get(0); // command 1
i.set(0, element); // command 2
}
}
コマンド1を検査する場合、変数タイプとして使用できないため、タイプをelement
に設定することしかできませんObject
(->上限の概念。マットの回答を参照) 。?
これ?
は、ジェネリック型が不明であることを示すためにのみ使用されます。
変数型は実数型またはジェネリック型のみですが、<T>
たとえばこのメソッドではジェネリック型を使用しないため、実数型を使用する必要があります。この強制は、Java仕様(jls8、18.2.1)の次の行のために行われます。
‹式→T›の形式の制約式は、次のように簡略化されます。
[...]
–式がクラスインスタンス作成式またはメソッド呼び出し式の場合、制約は、§18.5.2で定義されているように、Tをターゲットにするときに式の呼び出しタイプを決定するために使用されるバインドされたセットB3に縮小されます。(クラスインスタンス作成式の場合、推論に使用される対応する「メソッド」は§15.9.3で定義されています)。