首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java泛型类型擦除:何时发生和发生了什么?

Java泛型类型擦除:何时发生和发生了什么?
EN

Stack Overflow用户
提问于 2018-08-27 01:39:04
回答 2查看 0关注 0票数 0

很多站点(包括上面提到的官方教程)都说在编译时会发生类型擦除。如果在编译时完全删除了类型信息,那么当调用使用泛型的方法而没有类型信息或错误的类型信息时,JDK如何检查类型兼容性?

考虑以下示例:Say class A有一个方法,empty(Box<? extends Number> b),编译A.java并获取类文件A.class。

代码语言:javascript
复制
public class A {
    public static void empty(Box<? extends Number> b) {}
}
代码语言:javascript
复制
public class Box<T> {}
代码语言:javascript
复制
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());
    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-08-27 10:15:59

泛型由Java编译器实现为称为擦除的前端转换,可以将其视为源到源的转换,从而将通用版本loophole()转换为非泛型版本。

票数 0
EN

Stack Overflow用户

发布于 2018-08-27 11:20:27

具体化意味着通过专业化将某些抽象(参数类型)转换为具体(具体类型)

通过一个简单的例子说明这一点

具有定义的ArrayList:

代码语言:javascript
复制
ArrayList<T>
{
    T[] elems;
    ...//methods
}

是一个抽象,详细的一个类型构造函数,当专门用一个具体的类型时,会被“reified”,比如说Integer:

代码语言:javascript
复制
ArrayList<Integer>
{
    Integer[] elems;
}

但这正是 Java 没有的东西相反,他们不断地使用边界来抽象抽象类型,即生成相同的具体类型,而不依赖于传递给专业化的参数:

代码语言:javascript
复制
ArrayList
{
    Object[] elems;
}

这里用隐式绑定对象(ArrayList<T extends Object>== ArrayList<T>)进行了修改

尽管它使通用数组不可用并导致原始类型的一些奇怪的错误:

代码语言:javascript
复制
List<String> l= List.<String>of("h","s");
List lRaw=l
l.add(new Object())
String s=l.get(2) //Cast Exception

引起了很多含糊之处

代码语言:javascript
复制
void function(ArrayList<Integer> list){}
void function(ArrayList<Float> list){}
void function(ArrayList<String> list){}

参考相同的功能:

代码语言:javascript
复制
void function(ArrayList list)

因此,不能在Java中使用泛型方法重载。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100002408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档