2

質問1

class A {}
class B extends A {}

A aObj = new A();
B bObj = new B();

以下では、実行時にクラスキャスト例外が発生することがわかっています。

List<B> list_B = new ArrayList<B>();
list_B.add((B)aObj); //ClassCast exception

しかし

List<? extends A> list_4__A_AND_SubClass_A = new ArrayList<B>();
List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A;
list_A.add(aObj); // No exception here, Why?

質問2

以下のような方法で

void method(List<? extends A> list_4__A_AND_SubClass_A){
   //How do i find the passed list is of Type A or B ??
   // To decide List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A;
   //        OR List<B> list_B = (ArrayList<B>)list_4__A_AND_SubClass_A;
}

アップデート

Q_1

変更のために以下のようなコレクションを参照することは避けたほうがよいでしょう。渡されたリストが A/B のタイプであると確信している場合を除きます。そのリストの整合性を維持するために。

 List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A; 

Q_2

呼び出し元メソッドから呼び出し元メソッドにもう 1 つの引数を渡して、呼び出し元メソッドでの変更中にリストの整合性を維持できると思います。

void method(List<? extends A> list_4__A_AND_SubClass_A, Class<? extends A> obj){
     if (A.class.isAssignableFrom(obj)) {
         List<A> list_A = (List<A>)list_4__A_AND_SubClass_A;
            list_A.add(new A());
            list_A.add(new B());
     } else if (B.class.isAssignableFrom(obj)){
         List<B> list_B = (List<B>)list_4__A_AND_SubClass_A;
            //list_B.add(new A()); //only we can add B
            list_B.add(new B());
     }
}
4

3 に答える 3

2

理想的には、キャスト from List<B>toList<A>は実行時に例外をスローする必要があります。残念ながら、Java は実行時にそれを決定できません。幸いなことに、コンパイル時にそのキャストの警告が表示されます。

于 2013-03-06T19:14:44.607 に答える
1

この行:

List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A;

orBsを含むことができるリストにのみ含むリストをキャストする可能性がある (そして実際にキャストしている) (B は A のサブクラスであるため、それは IS であることを思い出してください) ため、「チェックされていない」警告が生成されます。BsAsA

list_A.add(aObj);

警告に注意を払わなかったので、まったく問題ありません。

一般に、ジェネリックでList< ? extends A>は、常に と同じではありませんList<A>

質問 2 に答えるには。
残念ながら、すべてのジェネリックはコンパイル時にチェックされ、実行時に利用できる情報はあまりないため、実行時にはオブジェクトのリストしかなく、それがどのようなリストであるかを効果的にテストすることはできません。この「機能」は、下位互換性とジェネリックが Java 1.5 で導入されたときのトレードオフでした。

于 2013-03-06T19:42:31.410 に答える
0
  1. ここList<? extends A>では、ワイルドカードタイプを定義しています。これは、リストが。Aまたはから派生したものをすべて受け入れることを意味しAます。したがって、例外はスローされません

  2. ここでは、リストの具体的な内部タイプを検出できません。これを直接渡す必要があります。つまり、メソッドのシグネチャは次のようになっている必要があります。

    voidメソッド(リストリスト)

于 2013-03-06T19:19:02.087 に答える