0

コード

Set<? extends MyClass> mySet = new HashSet<>();
mySet.add(new MyClass());

エラーメッセージを生成します。その理由は、コンパイラがmySetの型を認識していないためです。わかっているのは、mySetの型がSet<SomeType>であり、SomeTypeが MyType のサブタイプであることだけです。コンパイラはSet<? の型がわからないため です。extends MyClass>は、そのタイプのセットに挿入できる唯一のものを参照し、null です。

これは非常に紛らわしく、唯一可能な要素がnullであるセットの使用は最小限であるため、<? 上記の例のように、オブジェクトを宣言するときにSomeClass>を拡張します。この形式は、後で具象化される抽象化 (パラメーター、ジェネリック クラスまたはメソッドなど) を宣言する場合にのみ使用してください。

これは質問ではないことはわかっていますが、アイデアに対する反応はどうなのだろうか.

4

2 に答える 2

4

よくわかりません。想像できるのは、

Set<? extends MyClass> mySet = getOtherSet();

wheregetOtherSetの戻り値の型はSet<MySubClass>、または でさえありSet<? extends MyClass>ます。これは、ジェネリックの正当な使用であり、そうあるべきです。

上記の正当な使用とあなたが説明する問題のあるケースを区別する唯一の方法は、まさにJavaがすでに行っていることです.コンパイル時にエラーメッセージを生成します.

于 2012-04-21T23:36:30.067 に答える
0

Set<? extends MyClass>一般的には完全に便利なタイプです。、でメソッド引数を指定できます。これにより、またはSet<? extends MyClass>で呼び出すことができます。メソッドが実行する必要があるのが要素を取得することだけである場合、それは問題ありません。または、次のようなステートメントを持つことができますSet<OneClass>Set<AnotherClass>MyClass

Set<? extends MyClass> mySet = someObject.someMethod();

メソッドがさまざまなタイプのセットを返す可能性があり(一部のインスタンスはを返す場合がありSet<OneClass>、他のインスタンスはを返す場合がSet<AnotherClass>あります)、ここで行う必要があるのは、メソッドからMyClass物事を取得することだけです。

Set<? extends MyClass>あなたが示している例は、特に新しい空のセットでの初期化を扱っています。私は、このケースがそれほど有用ではないことに同意します。ただし、このケースを禁止するルールを作成する必要がある場合は、オブジェクト作成式の割り当てを、他の式(メソッド呼び出しなど)の割り当てとは異なるものにする必要があります(メソッド呼び出しは、単に戻ることもできます)。新しい空のセット)。害がない場合は、明示的に除外するのは無理だと思います。同様に、長さ0の配列を作成できることはかなり役に立たないので、許可しないようにする必要があると主張することもできます。ただし、エッジケースを処理できるようにすることで、言語がより一般的になります。

于 2012-04-22T05:13:11.087 に答える