4

ようやくジェネリックを理解したと思ったとき、次の例に出くわしました。

public class Organic<E> {
          void react(E e) { }
          static void main(String[] args) {
            //1: Organic<? extends Organic> compound = new Aliphatic<Organic>(); 
            //2: Organic<? super Aliphatic> compound = new Aliphatic<Organic>(); 
           compound.react(new Organic());
           compound.react(new Aliphatic());
           compound.react(new Hexane());
 } }
 class Aliphatic<F> extends Organic<F> { }
 class Hexane<G> extends Aliphatic<G> { }

1 行目のコメントを外すと、次のコードはコンパイルされません。

  compound.react(new Organic());  
  compound.react(new Aliphatic());  
  compound.react(new Hexane());

行 2 がコメント解除されている場合、次のコードはコンパイルされません。

compound.react(new Organic());

2 番目の例では、Aliphatic とそのスーパータイプが許可されています。では、なぜ脂肪族は許可されていないのでしょうか?

最初の例では、なぜnew Organic許可されないのですか??

最初のコンパイラ エラー:

- The method react(capture#1-of ? extends Organic) in the type Organic<capture#1-of ? extends Organic> is not applicable for the arguments (Organic)
- The method react(capture#2-of ? extends Organic) in the type Organic<capture#2-of ? extends Organic> is not applicable for the arguments (Aliphatic)
- The method react(capture#3-of ? extends Organic) in the type Organic<capture#3-of ? extends Organic> is not applicable for the arguments (Hexane)

2 番目のコンパイラ エラー:

- The method react(capture#1-of ? super Aliphatic) in the type Organic<capture#1-of ? super Aliphatic> is not applicable for the arguments  (Organic)
4

4 に答える 4

5

あなたの最初の宣言

Organic<? extends Organic> compound

( extends 、extends 、extendsであるため) であるcompound 可能性があることを意味します。Organic<SomeSubtypeOfHexane>AliphaticOrganicHexaneAliphaticSomeSubtypeOfHexaneHexane

その場合、 in は a (またはそのサブタイプ)でなければならないため、 compound.react(new Organic()), compound.react(new Aliphatic())andcompound.react(new Hexane())は型エラーにつながります。EcompoundSomeSubtypeOfHexane


あなたの2回目の宣言

Organic<? super Aliphatic> compound

compount である可能性があることを意味しますOrganic<Aliphatic>

その場合、 (またはそのサブタイプ)である必要があるcompound.react(new Organic())ため、型エラーが発生します。EAliphatic


A<? extends B>またはを使用して変数を宣言することを覚えておいてくださいA<? super B>

  • それに割り当てることができるオブジェクトの量を拡張し、その結果、
  • 変数でできることを制限します。

クラスの正確な型が不明であるため (制約のみが既知である)、コンパイラーは安全性の面で誤りを犯し、共変または反変でない特定の操作を許可しない必要があります。(まだよく知らない方のために説明すると、共変と反変は、これらのタイプのジェネリックの科学的背景です。)

于 2012-10-30T06:49:23.823 に答える
2

トピックの質問は、次のような他のいくつかの場所でも議論されています。

これは、実際にはJava 証明書の準備に関する本の質問であり、前回のテスト (質問 34) からのものです。予習書はレッスンブックをベースにしています。

ここと他のリンクの下にある説明と本に書かれている説明があっても、説明は主にList インターフェイスに基づいており、内部コレクション固有の解決策であると私が考えたことを読んだため、解決策は明確ではありませんでした。

しかし、一方にListインターフェースとaddメソッドの定義があり、他方にOrganicクラスとそのreactメソッドがあるのを見ると、それらが同様の方法で定義されていることに気付くでしょう。

public interface List<E> extends Collection<E> {
   ...
   boolean add(E e);
   ...
}

public class Organic<E> {
    ...
    void react(E e) { }
   ...
}                                               

したがって、どこにでもある List インターフェイスの例に基づくすべての説明は、この質問にも有効です。

List<? extends String> list1 = new ArrayList<String>();
List<? super String> list2 = new ArrayList<String>();
list1.add(new String()); //The method add(capture#1-of ? extends String) in the type List<capture#1-of ? extends String> is not applicable for the arguments (String) - // compile-time error
list2.add(new Object()); //The method add(capture#2-of ? super String) in the type List<capture#2-of ? super String> is not applicable for the arguments (Object) - // compile-time error

これについての説明を見てください:

于 2016-04-17T18:42:34.277 に答える
1

react()メソッドのパラメーターとして設定したものを誤解していると思います

変更してみる

void react(E e) { }

void react(Organic<E> e) { }

違いを見るために。オブジェクトを探しています:Organic<E> Aliphetic<E> Hexane<E>

Organic<E>ではないE

としてAliphetic<E>E

としてHexane<E>E

于 2012-10-30T06:42:04.207 に答える
0

あなたはいくつかのミックスを作りました。
Organic<E>の型は と同じOrganicです。
実行できません
new Organic()); 少なくとも実行を検討する必要があります
new Organic<Object>()); これは私が考えることができるコンパイル エラーの 1 つにすぎません
もちろん、これは他のオブジェクトのインスタンス化にも有効です。

于 2012-10-30T06:38:02.627 に答える