2012-02-09 6 views
0

OCJPの準備をしています。私は、6行目で独立して挿入された3つのコードの断片は、コンパイルされます関数はどのようにジェネリックスをJavaで実装しますか

import java.util.*; 
public class G1 { 
public void takeList(List<? extends String> list) { 
    // insert code here 
} 
} 

ダンプに問題を発見しましたか? (3つ選択してください。)

A. list.add("foo"); 
B. Object o = list; 
C. String s = list.get(0); 
D. list = new ArrayList<String>(); 
E. list = new ArrayList<Object>(); 

回答:B、C、D

私はList<? extends String場合にはStringクラスとStringクラスのすべてのサブクラスと一致する意味クエリを有します。

誰でも回答を正当化できますか?

+7

java.lang.Stringでは、最終的なクラスです。 – adatapost

+1

オプションAも有効です。 –

+0

コードオプションを実行しようとしました。エラーAを返します。 – coder25

答えて

4

Aが誤っている文字列であるとして、コンパイルされません。 (私はStringが最終的だと知っていますが、コンパイラはここでそれを気にしません)。 List<Object>に含まれるオブジェクトは必ずしもString型またはStringのサブクラスのものでないのでList<Object>は、明らかに、List<? extends String>に割り当てることができないので

Eが正しくありません。

他の三つのものはOKです:List<? extends String>がStringのインスタンス、またはのサブクラスのインスタンスが含まれているため、プリミティブ以外のすべては、Javaでのオブジェクト

  • CはOKですので

    • BはOKです文字列。また、サブクラスのインスタンスもスーパークラスのインスタンスです。
    • ArrayList<String>
    • List<String>あり、List<String>もリストは、文字列を拡張するもののリストとすることができるようにAがコンパイルされませんList<? extends String>
  • +0

    list.add( "foo")を使用できない理由を理解できません。 – coder25

    +0

    String以外の例を考えてみましょう。 'List <? Animal> extends Animal> Animal> extends Animal> Animal> extends Animal> Animal> Animal> extends Animalしたがって、 'List '、 'List '、または 'List 'である可能性があります。 'List 'で、 'list.add(new Chicken())'や 'list.add(new Animal())'を実行することができれば、リストの型安全性は完全に破壊され、それはDogインスタンスだけを含むはずだからです。そうすることは違法です。 –

    +0

    しかし、型の安全性が問題ならば、List <? Animal>が使用されています。リスト – coder25

    0

    Objectなので、Bが有効です。

    リストに格納されているものはどれも、ストリングにアップキャストすることができ、したがってCは有効です。ジェネリックで

    <? extends String>は」なし、文字列自体が存在そのStringのサブクラスを覆うので、Dは有効です。

    同様に、「<? super String>」は、StringまたはString'sのいずれかの継承ツリーを意味する。 ObjectCharSequenceSerializableなど

    1
    A. `list.add("foo");` 
    
    だけこのリストに nullを挿入することができるようになりますよう

    はコンパイルされません

    B. Object o = list; 
    

    コンパイル、リストには、オブジェクト

    C. String s = list.get(0); 
    
    あるとして

    リスト内のすべての要素が文字列オブジェクトまたはその理論上のサブクラスであることが保証されているのでコンパイルします(実際には不可能です。 ■Stringは最終クラスであり、拡張することはできません)。

    D. list = new ArrayList<String>(); 
    

    リスト内のすべての要素が文字列オブジェクトであることが保証されているため、コンパイルします。

    E. list = new ArrayList<Object>(); 
    

    リストはList<SomeStringSubClass>可能性があり、このようにそれに文字列を追加するには無効になるのではないすべてのオブジェクトは、

    Keep in mind that String is a final class and cannot be extended. 
    
    0

    あるため、DはOKです。ジェネリックスは、クラスが最終的なものかどうかの通知を受け取りません。

    単純な例では

    public void takeList(List<? extends Number> list) { 
        // insert code here 
        list.add(1.0); // not allowed. 
        Number n = list.get(0); // allowed. 
    } 
    
    // you could call it with 
    takeList(new List<BigInteger>()); 
    
    関連する問題