2016-04-17 8 views
0

ジェネリックスに関するOracleのチュートリアルを読んでいて、提供されているサンプルで何が間違っているかわかりませんでした。チュートリアルを引用Oracle Javaジェネリックチュートリアルボックスクラスの説明

(チュートリアルではhttps://docs.oracle.com/javase/tutorial/java/generics/types.html @見つけることができます):

は、任意のタイプのオブジェクトで動作する非ジェネリックBoxクラスを調べることから始めます。それを取得した、セット、ボックスにオブジェクトを追加し、取得:それは唯一の2つのメソッドを提供する必要が

public class Box { 
    private Object object; 

    public void set(Object object) { this.object = object; } 
    public Object get() { return object; } 
} 

その方法はObjectを受け入れるか返すので、あなたが好きに合格するのは自由ですただし、それは基本型の1つではありません。クラスの使用方法をコンパイル時に検証する方法はありません。コードの別の部分が誤って実行時エラーが生じ、Stringを渡すかもしれないが、コードの一部は、ボックス内の整数を配置し、それから整数を得ることを期待する。」私がしようとした

なぜそのランタイムエラーがそのような操作の結果であるのか解明できないので、私は自分のIDEで状況を再現し、コードを実行しましたが、エラーは発生しませんでした 私は間違っていますか? ?状況はここで

は、私は状況をテストするために作成したサンプルコードです:

Boxクラスの定義

public class Box 
{ 
private Object ob; 

    public Object getObject(){ 
     return ob; 
    } 

    public void setObject(Object ob){ 
     this.ob = ob; 
    } 
} 

テストBoxクラス

public class BoxTest 
{ 
    public static void run(){ 

     String sPar = "hello"; 
     Integer iPar = 45; 
     Box box = new Box(); 

     box.setObject(iPar); 
     System.out.println(box.getObject()); 

     box.setObject(sPar); 
     System.out.println(box.getObject()); 
    } 
} 

私はまた、プリミティブ型に渡そうとしましたし、それはまだ正常に動作...なぜランタイムエラーがこのような状況で発生するのでしょうか?

+1

あなたが別の型に戻り値をキャストしようとすると、ランタイム例外が発生します。 – Savior

+0

汎用クラスはプリミティブではなく参照型を要求します。 – Logan

+0

@Pillarおかげで、それは私が...私は、「これまで明確から」チュートリアルの説明 –

答えて

1

それはあなたが書くことができるという事実に言及されています

Box box = new Box(); 
box.setObject(Integer.valueOf(1)); 
String value = (String) box.getObject(); 

このコードは罰金コンパイルが、実行時にエラーが発生します。

一般的に、可能なすべてのタイプのテストが不足しています - タイプBox.getObject()が返されます。

キャストの使用はちょっと珍しいように見えるかもしれません。確かに、あなたは何を箱に入れたのかを常に知っているでしょう。あなたがStringを含むBoxパラメータを期待するメソッドを持っている、と言う、かどうかは、知ることはできないだろう。

void doSomethingToStringBox(Box box) { 
    String value = (String) box.getValue(); 
} 

あなたは(少なくともそれが見えるところから)あなたのコード内のどこからこれを呼び出すことができますそのコードを書く人がBoxStringが含まれていなければならないことを100%確信することはできません。それはまだ可能であるため、私は、上記の "正しく" という言葉を強調

Box<Integer> box = new Box<>(); 
box.setObject(Integer.valueOf(1)); 
// Compiler error - Integer cannot be cast to String. 
String value = (String) box.getObject(); 

または

Box<String> box = new Box<>(); 
// Compiler error - Integer cannot be converted to String 
box.setObject(Integer.valueOf(1)); 
String value = box.getObject(); 

:あなたは が正しくは、クラスのジェネリック版を使用していた場合


ジェネリックなしgenericized Boxを使用します

Box box = new Box(); 

、その後、あなたが戻って非常に最初の例と同じタイプ、危険な状況にいます。

これは生タイプと呼ばれ、あなたが今作成したコードでは使用しないでください。レガシーコードとの下位互換性のために許可されており、将来サポートされなくなる可能性があります。

+0

説明ありがとうございましたAndy –