java类,继承generic method 后,不能调用superclass的函数

我是java的初学者。
我对java泛型中的erase特别想不通
有一个例子

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

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

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

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

照理来说,经过了erase之后,Node这个类就可以改写成为:

public class Node {

    public Object data;

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

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

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

由于MyNode继承了Node,所以MyNode有两个setData method:
void setData(Object data)和public void setData(Integer data).
现在,如果我有一个main()来运行代码:

class Solution {
    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");
    }
}

照理来说,虽然根据多态,run-time的时候会先搜索到public void setData(Integer data),但是当JVM发现不匹配的时候,应该会去运行super class的public void setData(Object data),因此不应该run-time error.
并且,根据https://docs.oracle.com/javas... 照理来说,这段代码应该也是没问题的。
但是我运行的时候出现了

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at MyNode.setData(MyNode.java:1)
at Solution.main(Solution.java:83)

但是,这段代码却可以正常运行:

public static void main(String[] args) {
        MyNode mn = new MyNode(5);
        Node n = mn;
        // inherit set from the Node            
        n.set("Hello");
}

所以,为什么同样是继承了public函数,如果subclass中没有同名的method,superclass的method是可以被正常调用的,但是如果有同名的method,superclass的method就不能正常运行了?

java版本:

java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

繁花不似锦
浏览 506回答 1
1回答

忽然笑

对于编译器来说,它理解你的MyNode#setData(Integer data) 是要覆盖父类Node#setData(Object data)所以会生成一个桥方法MyNode#setData(Object data)用于重写父类的setData方法。 MyNode#setData实现如下 public void setData(Object obj){ //所以出现了ClassCastException setData((Integer)obj); }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java