0

次のコードは、ジェネリックの Oracle ドキュメントから取られています -

 class Node<T> {

    public 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); }

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

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

このコードの私の理解 -

Q - メソッドはsetDataオーバーライドまたはオーバーロードされていますか?

私の理解では、MyNodeが拡張されているためNode<Integer>、type パラメータの値Tが に設定されていIntegerます。

そのため、クラスには T= Integer のNodeメソッドがあり、クラスにはメソッドがあります。setData(Integer data)MyNodesetData(Integer data)

署名が同じであるため、オーバーライドされます。

Q- メソッド setData は消去後でもオーバーライドされますか? 私の理解 -

<T>設定方法を消してからにNodeなり、setData(Object data)

の set メソッドはMynode-setData(Integer data)型パラメーターがないため、削除するものは何もありません。

しかし、これは過負荷です。

Q - オーバーロードまたはオーバーライドが必要でしたか?

私の理解 - 消去前に定義されたメソッドの外観から、オーバーライドが必要でした。

Q - 消去後のオーバーライドを達成するにはどうすればよいですか?

私の理解 -ブリッジ法による。例えば:

setData(Object data){
    setData((Integer) Data);
}

私の理解は正しいですか?

また、 class MyNode extends Node<Integer>いつにInteger渡され<T>ますか? スーパーが呼び出されたとき?

4

1 に答える 1

1
  1. はい、メソッドsetDataはオーバーライドされます。
  2. ユーザーの観点からは、setData(T data)によってオーバーライドされているように見えますsetData(Integer i)。つまり、 を呼び出すと、 "Node"ではなく"MyNode"setData(42)で何かが出力されます。

    タイプ消去メソッド シグネチャのレベルでは、これは に合成ブリッジ メソッドsetData(Object)を追加することによって実現されMyNodeます。つまり、 で逆コンパイルMyNode.classすると、次の 2 つのメソッドjavapが表示されます。

      public void setData(java.lang.Integer);
      public void setData(java.lang.Object);
    
  3. 言語仕様には「オーバーライド」と書かれていますが、なぜ他のものが必要なのかわかりません。

  4. 「消去後にオーバーライドを実現する」という意味が明確ではありません。型の消去は、型のチェックと、何が何をオーバーライドするかを決定した後に行われます。「達成」するものは何もありません。それは物事が機能する順序です(このコメントも参照してください)。オリジナルをオーバーライドする合成ブリッジング方法は、setData(Object)あなたが書いたもののように見えます (小さなタイプミスまで):

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

    少なくとも、ドキュメントにはそう書かれています。ただし、これは合成メソッドであり、コンパイラによって自動的に生成されます。ソース コードに含まれていると、コンパイル エラーが発生します。

于 2019-04-21T15:17:28.543 に答える