私は最近Javaジェネリックスを学んでいますが、 "Java Generics FAQ"に行きます。Javaジェネリックスワイルドカードの混乱
ワイルドカードのパラメータ化された型に関する疑問(#304)は私には分かりませんが、助けていただければ幸いです。
コード例:
boolean equal = box.equalTo(box);
equal = box.equalTo(new Box<String>("abc"));
おかげ
私は最近Javaジェネリックスを学んでいますが、 "Java Generics FAQ"に行きます。Javaジェネリックスワイルドカードの混乱
ワイルドカードのパラメータ化された型に関する疑問(#304)は私には分かりませんが、助けていただければ幸いです。
コード例:
boolean equal = box.equalTo(box);
equal = box.equalTo(new Box<String>("abc"));
おかげ
Box<?> box = new Box<String>("abc");
box.put("xyz"); // error
String s = box.take(); // error
を、あなたはポリモーフィズムを使用しています。だから、時間をコンパイル時に、ボックスオブジェクトのタイプは、Box<?>
Type<?>
これは未知のワイルドカードと呼ばれています。タイプされているボックスのタイプがわからないので、そのオブジェクトからのみ読み取ることができ、読み取られたオブジェクトはObjectインスタンスとしてのみ使用できます。だからbox.put("xyz")
が受信エラーで、String s = box.take()
が受信エラーです。第二に
は:
boolean equal = box.equalTo(box);
equalTo
はないBox<?>
Box<T>
受信されます。上で説明したように、Tはクラスを表しますが、?
は未知のワイルドカードを意味し、これらの2つの用語は同じではありません。
あなたが知っておくべき他のポイント。 Javaでは、ジェネリックはコンパイル時です。 C#のような他のものと対照的に、ジェネリックは実行時にあります。ここで
は、ワイルドカードについての参照リンクである:このヘルプ:)
equalTo
方法はBox<T>
、ないBox<?>
取ります
class Box<T> {
private T t;
public Box(T t) { this.t = t; }
public void put(T t) { this.t = t;}
public T take() { return t; }
public boolean equalTo(Box<T> other) { return this.t.equals(other.t); }
public Box<T> copy() { return new Box<T>(t); }
}
class Test {
public static void main(String[] args) {
Box<?> box = new Box<String>("abc");
box.put("xyz"); // error
box.put(null); // ok
String s = box.take(); // error
Object o = box.take(); // ok
boolean equal = box.equalTo(box); // error {confused}
equal = box.equalTo(new Box<String>("abc")); // error {confused}
Box<?> box1 = box.copy(); // ok
Box<String> box2 = box.copy(); // error
}
}
が失敗すると呼ばれる理由は、以下の2つの方法を把握することはできません。 Box<?>
のオブジェクトを持っている場合、Box<String>
またはBox<?>
をパラメータとしてequalTo
に設定することはできません。これは、2つのボックスのタイプが同じでない可能性があるからです(T
)。
コンパイラはコンパイル時にオブジェクトの静的型を使用することに注意してください。
だから、これは失敗します。
Box<?> b = new Box<String>();
b.equalTo(new Box<String>("abc");
しかし、これはしません:OOPで
Box<String> b = new Box<String>();
b.equalTo(new Box<String>("abc");
が理由と呼ばれる2つの方法の下に把握することはできませんJava wildcard
希望はこれがあるので、彼らは失敗
を失敗しますワイルドカードの仕組み
ワイルドカードは「わからない種類」を表します。
もっと簡単なクラスを作ってみましょう。
class Holder<T> {
private T obj;
void set(T obj) {
this.obj = obj;
}
T get() {
return obj;
}
}
Holder<?>
がある場合、私たちはそれにアクセスするための特別なルールを持っています。特に、一般的な引数を持つメソッドを呼び出すことはできません。これは、私たちがどんなタイプのものであるかわからないからです。そうすることは危険です。
class Holder<?> {
private X obj;
void set(X obj) {
this.obj = obj;
}
Object get() {
return obj;
}
}
X
は、我々はそれはもうあるかわからないので、タイプは立ち入り禁止私たちにあることを意味:私たちはHolder<?>
を持っている場合は
は、我々は(概念的には)のようなものを持っています。
get
戻っObject
それは我々がobj
があることを確認することができます唯一のクラスであるためset
私はこれがあなたのequalTo
が元々のように宣言されたのであれば奇妙に思えるかもしれないと仮定し、すべてので呼び出すことはできません
public boolean equalTo(Box<?> other);
あなたはそれを呼び出すことができます。ただし、ワイルドカードはT
を?
に置き換えるだけでは機能しません。
Box<?>
は「不明のボックス」です。 Box<? extends String>
Box<String>
は間違いある「文字列の箱」になります。null
を「不明のボックス」に入れることはできますか?確かに。Box<?> box = new Box<String>("abc");
はその約<String>
を忘れるとbox
は "不明の箱" であると仮定するコンパイラを求め、ということを考えると
。表示されるエラーは、コンパイラが引き続き引数の型チェックを行うことができないことを示します。指定された型が未知であるかどうかをチェックすることはできません(nullを除く)。
エラーは何を意味し、何について理解していますか? –
@SotiriosDelimanolisはequalTo()のパラメータがボックス>であると考えていて、ボックス>が引数として "box"と "new Box(" abc ")"を受け入れることができない理由を理解していません。 –
foolhunger
エラーと言うと、コンパイラエラーまたはランタイムエラーを意味しますか? – smac89