2
package practice;

class Node<T> {

    T data;

    public Node(T data) { this.data = data; }

    public void setData(T data) {
        System.out.println("Node.setData");
        this.data = data;
    }
}

class MyNode extends Node<Integer> {
    public MyNode(Integer data) { super(data); }

    @Override
    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
}

public class Practice {
    public static void main(String[] s)
    {
        MyNode mn = new MyNode(5);
        Node n = mn;            // A raw type - compiler throws an unchecked warning
        n.setData("Hello");     // Causes a ClassCastException to be thrown.
        Integer x = mn.data;    
    }
}

n.setData("Hello");実際には で例外をスローする必要があるのに、このコードが で例外をスローするのはなぜInteger x = mn.data;ですか?

http://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html

4

4 に答える 4

2

文字列値を整数変数に設定しようとしているためです。

于 2012-09-09T10:22:04.413 に答える
1

チュートリアルに小さな間違いがあると思います: エラーは次の行でスローされると言うべきでしたn.setData("Hello");

これは、呼び出すときn.setData("Hello");クラスでブリッジ メソッドを呼び出すためです。そうしないと、コンパイル時にエラーが発生します。n.setData(Object object) MyNode

しかし、ブリッジメソッドは次のようになります。

// Bridge method generated by the compiler
//
public void setData(Object data) {
    setData((Integer) data);
}

setData(Integer anInt)ブリッジが のキャストを使用してを呼び出そうとしていることがわかりますdata。を提供したため、このキャストは失敗しますString

この例で興味深いのは、@Override注釈を使用しても、技術的にはオーバーライドしなくてもコンパイル時エラーが発生しないことですが、コンパイラは後でオーバーライドします。アノテーションは、 が onではなく onsetData(Object object)で呼び出されることを通知するのに非常に便利です。これは、メッセージが表示されない理由を説明しています。MyNodeNodeSystem.out

于 2012-09-09T10:59:32.987 に答える
1

を呼び出して、 の型Tをすでに定義しています。Node

MyNode mn = new MyNode(5);

つまりIntegerタイプ。呼び出すn.setData("Hello");ことにより、整数フィールドの文字列変数を渡そうとしています。Nodeは、型指定された Nodenの単なる参照です。Integermn

于 2012-09-09T10:22:27.317 に答える
0

の型は、n実際Integerには から受け取ったmnです。

と同じ原理です。List list = new ArrayList();

ここのリストは実際には ですがArrayList、List インターフェイスを使用してのみ参照されます。同様に、 は ですnNode、その実装はMyNodeのみを受け入れるIntegerです。それがあなたが入れることができる理由StringですsetData()

編集例を読んだら

ページには、ブリッジメソッドが次のように作成されると記載されています。

class MyNode extends Node {

    // Bridge method generated by the compiler
    //
    public void setData(Object data) {
        setData((Integer) data);
    }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }

    // ...
}

bridge メソッドは次のことを行います。

public void setData(Object data) {
            setData((Integer) data);
        }

ここでは、String「Hello」であるデータを にキャストしようとしていIntegerます。したがって、エラーがスローされます。

于 2012-09-09T10:23:43.540 に答える