为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁花不似锦 2019-03-01 10:29:10
我是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)
查看完整描述

1 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

对于编译器来说,它理解你的MyNode#setData(Integer data) 是要覆盖父类Node#setData(Object data)
所以会生成一个桥方法MyNode#setData(Object data)用于重写父类的setData方法。

MyNode#setData实现如下

public void setData(Object obj){
    //所以出现了ClassCastException 
    setData((Integer)obj); 
}
查看完整回答
反对 回复 2019-03-01
  • 1 回答
  • 0 关注
  • 505 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信