很多站点(包括上面提到的官方教程)都说在编译时会发生类型擦除。如果在编译时完全删除了类型信息,那么当调用使用泛型的方法而没有类型信息或错误的类型信息时,JDK如何检查类型兼容性?
考虑以下示例:Say class A有一个方法,empty(Box<? extends Number> b),编译A.java并获取类文件A.class。
public class A {
public static void empty(Box<? extends Number> b) {}
}
public class Box<T> {}
public class B {
public static void invoke() {
// java: unchecked method invocation:
// method empty in class A is applied to given types
// required: Box<? extends java.lang.Number>
// found: Box
// java: unchecked conversion
// required: Box<? extends java.lang.Number>
// found: Box
A.empty(new Box());
}
}
发布于 2018-08-27 10:15:59
泛型由Java编译器实现为称为擦除的前端转换,可以将其视为源到源的转换,从而将通用版本loophole()
转换为非泛型版本。
发布于 2018-08-27 11:20:27
具体化意味着通过专业化将某些抽象(参数类型)转换为具体(具体类型)
通过一个简单的例子说明这一点
具有定义的ArrayList:
ArrayList<T>
{
T[] elems;
...//methods
}
是一个抽象,详细的一个类型构造函数,当专门用一个具体的类型时,会被“reified”,比如说Integer:
ArrayList<Integer>
{
Integer[] elems;
}
但这正是 Java 没有的东西!相反,他们不断地使用边界来抽象抽象类型,即生成相同的具体类型,而不依赖于传递给专业化的参数:
ArrayList
{
Object[] elems;
}
这里用隐式绑定对象(ArrayList<T extends Object>
== ArrayList<T>
)进行了修改
尽管它使通用数组不可用并导致原始类型的一些奇怪的错误:
List<String> l= List.<String>of("h","s");
List lRaw=l
l.add(new Object())
String s=l.get(2) //Cast Exception
引起了很多含糊之处
void function(ArrayList<Integer> list){}
void function(ArrayList<Float> list){}
void function(ArrayList<String> list){}
参考相同的功能:
void function(ArrayList list)
因此,不能在Java中使用泛型方法重载。
https://stackoverflow.com/questions/-100002408
复制相似问题