繁体   English   中英

在Java中键入擦除意外行为

[英]Type erasure unexpected behavior in Java

根据Java关于类型擦除有界类型参数的文档,我理解在下面的代码示例中,两个版本的doStuff()将具有相同的擦除,因此将无法编译。 我的目标是重载doStuff()以接收ClassOneClassTwo

import java.util.List;

class Example {
  class ClassOne {
  }

  class ClassTwo {
  }

  public void doStuff(List<ClassOne> collection) {
  }

  public void doStuff(List<ClassTwo> collection) {
  }
}

类型擦除的机制包括以下步骤:

·如果类型参数是无界的,则泛型或对象替换泛型类型中的所有类型参数。 因此,生成的字节码仅包含普通的类,接口和方法。

因此,我应该能够应用一个绑定,然后它将编译,因为现在类型擦除版本的doStuff重载了两个不同的签名(声明的上限)。 例:

class Example {
  class ClassOne {
  }

  class ClassTwo {
  }

  public <U extends ClassOne> void doStuff(List<U> collection) {
  }

  public <U extends ClassTwo> void doStuff(List<U> collection) {
  }
}

第二个例子实际上没有编译并给出以下错误:

错误:(15,36)java:name clash:doStuff(java.util.List)和doStuff(java.util.List)具有相同的擦除

任何人都可以向我解释这个吗?

问题是List<U>将在您的两种方法中简化为List (擦除后不能List<ClassOne>List<Object> 。)

您引用的段落意味着可以拥有以下声明:

class Example {
    class ClassOne {
    }

    class ClassTwo {
    }

    public <U extends ClassOne> void doStuff(U foo) {
    }

    public <U extends ClassTwo> void doStuff(U foo) {
    }
}

这里的泛型参数将分别由ClassOneClassTwo替换,这样可以正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM