Java泛型类型擦除:字段上的运行时类型检查
我正在学习关于泛型的Java教程,并以自己的方式在上玩示例 两类:Java泛型类型擦除:字段上的运行时类型检查,java,Java,我正在学习关于泛型的Java教程,并以自己的方式在上玩示例 两类: public class Node<T> { private T data; public Node(T data) { this.data = data; } public void setData(T data) { this.data = data; } } public class MyNode extends Node<In
public class Node<T> {
private T data;
public Node(T data) {
this.data = data;
}
public void setData(T data) {
this.data = data;
}
}
public class MyNode extends Node<Integer> {
public MyNode(Integer data) {
super(data);
}
public void setData(Integer data) {
super.setData(data);
}
}
因为第3行实际上调用的是类型擦除方法Node.setData(Object)。但是将抛出运行时ClassCastException
这是我的实验:我打印出字段数据的类型。它在Node和MyNode中都是对象
以下是我的问题:
节点有一个对象
类型,由于类型擦除,这并不奇怪。但是为什么MyNode也有一个“数据”的对象类型呢
如果MyNode的“数据”具有对象
类型,那么运行时类型检查是如何工作的?(ClassCastException
exception…)在我看来,MyNode中的数据类型也被删除了(我的谜题#1)
Java版本:HotSpot 1.8.0_05-b13这与
泛型
或类型擦除无关
您正在告诉编译器节点n
,但没有提供任何类型,因此它将接受任何内容
这与将ArrayList
下放到List
并抱怨它需要任何东西没有什么不同
final List los=new ArrayList();
新增服务水平(新日期());
增加(1);
这是一个定义良好的预期行为,它是按照你的要求去做的
除了确切地告诉它做什么,你还期望它做什么?这与泛型
或类型擦除
无关
您正在告诉编译器节点n
,但没有提供任何类型,因此它将接受任何内容
这与将ArrayList
下放到List
并抱怨它需要任何东西没有什么不同
final List los=new ArrayList();
新增服务水平(新日期());
增加(1);
这是一个定义良好的预期行为,它是按照你的要求去做的
除了确切地告诉它做什么,你还期望它做什么?
我打印出了字段数据的类型
您可能打印出来的是一个名为“data”的引用类型。它确实设置为对象
但是为什么MyNode也有“数据”的对象类型呢
不确定你在谈论哪些数据。局部变量数据
的引用类型将是整数
,而属性引用类型是对象
如果MyNode的“数据”具有对象类型,那么运行时类型检查是如何工作的?(ClassCastException异常…)在我看来,MyNode中的数据类型也被删除了(我的谜题#1)
执行此操作时:
public void setData(Integer data) {
super.setData(data);
}
Java编译器将其转换为:
public void setData(Object arg) {
Integer data = (Integer) arg;
//Now you can use "data" refenrence with proper type
super.setData(data);
}
这就是ClassCastException的来源
我打印出了字段数据的类型
您可能打印出来的是一个名为“data”的引用类型。它确实设置为对象
但是为什么MyNode也有“数据”的对象类型呢
不确定你在谈论哪些数据。局部变量数据
的引用类型将是整数
,而属性引用类型是对象
如果MyNode的“数据”具有对象类型,那么运行时类型检查是如何工作的?(ClassCastException异常…)在我看来,MyNode中的数据类型也被删除了(我的谜题#1)
执行此操作时:
public void setData(Integer data) {
super.setData(data);
}
Java编译器将其转换为:
public void setData(Object arg) {
Integer data = (Integer) arg;
//Now you can use "data" refenrence with proper type
super.setData(data);
}
这就是ClassCastException的来源。为什么要覆盖setData
方法。因为您继承了它,所以不需要重新实现它。覆盖正是测试的重点。它说明了这个问题。为什么要覆盖setData
方法。因为您继承了它,所以不需要重新实现它。覆盖正是测试的重点。这说明了问题所在,这是一个很好的观点。引用类型在这里没有任何意义,因为编译器重写setData(Object)
。我已经运行了一个javap-c
来确认它。谢谢,这是一个很好的观点。引用类型在这里没有任何意义,因为编译器重写setData(Object)
。我已经运行了一个javap-c
来确认它。谢谢,你误解了我的问题。我一点也不惊讶于这种类型的删除。我实际上是在为我的实验制造问题。我问的是运行时类型检查。请查看另一个答案。这与擦除无关,与以下事实有关:节点n
上没有类型信息,没有“擦除”内容,它是对象
如果没有其他内容,请再次检查问题帖子和所选答案。这个问题与节点无关。你误解了我的问题。我一点也不惊讶于这种类型的删除。我实际上是在为我的实验制造问题。我问的是运行时类型检查。请查看另一个答案。这与擦除无关,与以下事实有关:节点n
上没有类型信息,没有“擦除”内容,它是对象
如果没有其他内容,请再次检查问题帖子和所选答案。这个问题与节点
无关。