【发布时间】:2020-06-20 21:54:30
【问题描述】:
这是作者在书中提供的关于泛型编程的代码示例:
public class Pair<T>
{
private T first;
private T second;
public Pair() { first = null; second = null; }
public Pair(T first, T second) { this.first = first; this.second = second; }
public T getFirst() { return first; }
public T getSecond() { return second; }
public void setFirst(T newValue) { first = newValue; }public void setSecond(T newValue) {
second = newValue; }
}
接下来作者介绍类型擦除机制
无论何时定义泛型类型,都会自动提供相应的原始类型。这 原始类型的名称只是泛型类型的名称,删除了类型参数。 类型变量被擦除并替换为它们的边界类型(或者例如,原始的 为无边界变量的 Object 类型)。
您的程序可能包含不同类型的擦除将它们全部变成原始 Pair ,例如
Pair<String>或Pair<LocalDate>,但擦除会将它们全部转换为原始 Pair 类型。
所以对于class Pair<T>的情况,擦除后变成下面的raw Pair类型:
public class Pair
{
private Object first;private Object second;
public Pair(Object first, Object second)
{
this.first = first;
this.second = second;
}
public Object getFirst() { return first; }
public Object getSecond() { return second; }
public void setFirst(Object newValue) { first = newValue; }
public void setSecond(Object newValue) { second = newValue; }
}
所以如果我们运行代码,打印 TURE
Pair<Integer> p = new Pair<Integer>(1, 2);
Pair<String> s = new Pair<String>("a", "b");
System.out.println(p.getClass()==s.getClass());
问题来了,当我创建一个类型错误的Pair<T> 实例时,例如:
Pair<String> s = new Pair<String>("a", 1);
编译器可以找出问题并打印此消息:
pair1/PairTest1.java:12:错误:不兼容的类型:int 不能 转换为字符串 对 s = new Pair("a", 1);
因为 <T> 被擦除为 Object 并且构造函数变为:
public Pair(Object first, Object second)
{
this.first = first;
this.second = second;
}
而参数类型变成了Object,所以:
编译器如何判断类型错误?或类型擦除何时发生?
【问题讨论】:
-
类型擦除什么时候发生?编译后。
-
不,它发生在编译期间,但编译器并没有忘记原始声明。 @JohannesKuhn
标签: java types casting type-conversion jvm