3

メソッドを持つ検証インターフェースをすべて実装するクラスのグループがありますisValid()。オブジェクトのグループ(すべての異なるクラス)をArrayListに入れ、それらをループしてそれぞれを呼び出したいと思いますisValid()

これが私のコードです

Email email = new email();
Address address = new Address();

ArrayList<? extends Validation> myValidationObjects = new ArrayList();

しかし、私がやろうとすると:

myValidationObjects.add(email);

私は得る:

ArrayList型のメソッドadd(capture#2-of?extends Validation)は、引数には適用できません(Eメール)

と検証の両方Emailを実装します。Address

このドキュメントによるとextends、インターフェイスとサブクラスの両方に使用できるはずです。

4

4 に答える 4

7

List<? extends Validation> myValidationObjects

誤った読み方

myValidationObjectsは拡張するオブジェクトのリストですValidation。」

正しい読み方

"myValidationObjectsは、拡張する任意のタイプのリストにすることがValidationできます。たとえば、List<RangeValidation>またはList<RegexValidation>。"

List<RangeValidation>aとaの両方に合法的に追加できるオブジェクトがないためList<RegexValidation>、Javaではaddそのようなタイプの変数を呼び出すことができません。

あなたのケースは実際にはもっと単純なものです:あなたは明確なタイプが必要ですList<Validation>

于 2013-01-04T20:38:04.123 に答える
5

次を使用できます。

List<Validation> myValidationObjects = new ArrayList<>();           // Java 7
List<Validation> myValidationObjects = new ArrayList<Validation>(); // pre Java 7

Validationこれで、そのリストに実装するクラスの任意のインスタンスを追加できます。

于 2013-01-04T20:35:16.247 に答える
2

宣言ArrayList<? extends Validation>は、を拡張する未知のクラスのリストを意味しますValidationEmailこの不明なクラスとは互換性がありません。

ArrayList<Validation>あなたはあなたのリストに使うことができます。

于 2013-01-04T20:37:12.843 に答える
2

ジェネリッククラスT<? extends Foo>である場合、取るメソッドに渡すことができるのTnull-を拡張するサブクラスではないFooことだけです。

その理由は、List<? extends Validation>「検証を拡張するもののリスト」を意味するものではないからです。あなたはただでそれを得ることができますList<Validation>。代わりに、「そのタイプが検証を拡張するような、あるタイプのリスト」を意味します。

これは微妙な違いですが、基本的にList<? extends T>はのサブタイプであるList<T>ため、何も挿入できないようにする必要があります。この場合を考えてみてください。

List<FooValidation> foos = new ArrayList<>();
List<? extends Validation> validations = foos; // this is allowed
validations.add(new BarValidation()); // not allowed! this is your question
FooValidation foo = foos.get(0);

3行目が許可されている場合、最後の行はClassCastExceptionをスローします。

于 2013-01-04T20:37:57.947 に答える