java 泛型和类型擦除_关于Java泛型和擦除

java 泛型和类型擦除

“编译期间擦除泛型”是常识(好吧,类型参数和实参实际上是被擦除的)。 这是由于“类型擦除”而发生的。 但这是错误的,正如许多开发人员所假设的那样,将<..>符号内指定的所有内容都删除了。 请参见下面的代码:

public class ClassTest {
  public static void main(String[] args) throws Exception {
    ParameterizedType type = (ParameterizedType) 
       Bar.class.getGenericSuperclass();
    System.out.println(type.getActualTypeArguments()[0]);
    
    ParameterizedType fieldType = (ParameterizedType) 
        Foo.class.getField("children").getGenericType();
    System.out.println(fieldType.getActualTypeArguments()[0]);
    
    ParameterizedType paramType = (ParameterizedType) 
        Foo.class.getMethod("foo", List.class)
        .getGenericParameterTypes()[0];
    System.out.println(paramType.getActualTypeArguments()[0]);
    
    System.out.println(Foo.class.getTypeParameters()[0]
        .getBounds()[0]);
  }
  
  class Foo<E extends CharSequence> {
    public List<Bar> children = new ArrayList<Bar>();
    public List<StringBuilder> foo(List<String> foo) {return null; }
    public void bar(List<? extends String> param) {}
  }
   
  class Bar extends Foo<String> {}
}

你知道那是什么吗?

类java.lang.String
类ClassTest $ Bar
类java.lang.String
类java.lang.StringBuilder
接口java.lang.CharSequence

您会看到每个类型的参数都会保留下来,并且可以在运行时通过反射进行访问。 但是,什么是“类型擦除”? 必须删除某些内容吗? 是。 实际上,除结构化结构外,其他所有结构均与之相关–上面的所有内容都与类的结构有关,而不是与程序流有关。 换句话说,有关类的类型参数及其字段和方法的元数据被保留以通过反射进行访问。

但是,其余部分将被删除。 例如,以下代码:

List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();
while (it.hasNext()) {
   String s = it.next();
}

实际上将被转换为此(两个片段的字节码相同):

List list = new ArrayList();
Iterator it = list.iterator();
while (it.hasNext()) {
   String s = (String) it.next();
}

因此,将删除您在方法主体中定义的所有类型参数,并在需要的地方添加强制类型转换。 另外,如果定义了一个方法以接受List<T> ,则此T将被转换为Object(或如果声明了其边界,则转换为它的边界。这就是为什么您不能执行new T() (顺便说一句,有关此擦除的公开问题 )。

到目前为止,我们已经介绍了类型擦除定义的前两点。 第三个是关于桥接方法。 我已经用这个stackoverflow问题(和答案)进行了说明

所有这两个“道德”。 首先,java泛型很复杂。 但是您可以在不了解所有复杂性的情况下使用它们。

其次,不要假设所有类型信息都被删除了-结构类型参数在那里,因此,如果需要,可以使用它们(但不要过分依赖反射)。

翻译自: https://www.javacodegeeks.com/2014/11/on-java-generics-and-erasure.html

java 泛型和类型擦除

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值