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

因为您正在尝试将 String 值设置为 Integer 变量。

于 2012-09-09T10:22:04.413 回答
1

您已经通过调用定义T了类型Node

MyNode mn = new MyNode(5);

Integer类型。通过调用n.setData("Hello");,您正在尝试为 Integer 字段传入 String 变量。Noden只是Integer类型化 Node的一个引用mn

于 2012-09-09T10:22:27.317 回答
1

我认为教程中有一个小错误:他们应该说错误是在行抛出的n.setData("Hello");

那是因为当你调用时,n.setData("Hello");你调用了 bridge 方法: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即使您在技术上没有覆盖,但编译器稍后会覆盖,使用注释时也不会出现编译时错误。注释在这里非常有用,用于通知setData(Object object)将被调用 onMyNode而不是 on Node。这解释了为什么您看不到任何System.out消息。

于 2012-09-09T10:59:32.987 回答
0

因为它的类型n实际上是Integer从它接收到的mn

原理是一样的List list = new ArrayList();

这里的列表实际上是一个ArrayList,但仅使用 List 接口引用。同样,即使n是 a Node,它的实现也是 aMyNode只接受IntegerString这就是为什么你可以放入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);
    }

    // ...
}

桥接方法执行以下操作

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

在这里,它试图将作为String“Hello”的数据转换为Integer. 因此抛出错误。

于 2012-09-09T10:23:43.540 回答