简体   繁体   English

在Java中键入擦除意外行为

[英]Type erasure unexpected behavior in Java

According to Java's documentation on Type Erasure and Bounded Type Parameters , I understand that in the code example below both versions of doStuff() will have the same erasure and, therefore, won't compile. 根据Java关于类型擦除有界类型参数的文档,我理解在下面的代码示例中,两个版本的doStuff()将具有相同的擦除,因此将无法编译。 My goal is to overload doStuff() in order to receive collections of ClassOne and ClassTwo . 我的目标是重载doStuff()以接收ClassOneClassTwo

import java.util.List;

class Example {
  class ClassOne {
  }

  class ClassTwo {
  }

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

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

Mechanics for type erasure include the following step: 类型擦除的机制包括以下步骤:

· Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. ·如果类型参数是无界的,则泛型或对象替换泛型类型中的所有类型参数。 The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods. 因此,生成的字节码仅包含普通的类,接口和方法。

Therefore, I should be able to apply a bound and then it would compile because now the type erased version of doStuff is overloaded with two different signatures (the declared upper bounds). 因此,我应该能够应用一个绑定,然后它将编译,因为现在类型擦除版本的doStuff重载了两个不同的签名(声明的上限)。 Example: 例:

class Example {
  class ClassOne {
  }

  class ClassTwo {
  }

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

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

This second example actually doesn't compile and gives the following error: 第二个例子实际上没有编译并给出以下错误:

Error:(15, 36) java: name clash: doStuff(java.util.List) and doStuff(java.util.List) have the same erasure 错误:(15,36)java:name clash:doStuff(java.util.List)和doStuff(java.util.List)具有相同的擦除

Can anyone explain this to me? 任何人都可以向我解释这个吗?

The problem is that List<U> will be reduced to just List in both your methods. 问题是List<U>将在您的两种方法中简化为List (You can't have List<ClassOne> or List<Object> left after erasure.) (擦除后不能List<ClassOne>List<Object> 。)

The passage you quote means that it is ok to have the following declaration: 您引用的段落意味着可以拥有以下声明:

class Example {
    class ClassOne {
    }

    class ClassTwo {
    }

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

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

Here the generic arguments will be replaced by ClassOne and ClassTwo respectively, which works just fine. 这里的泛型参数将分别由ClassOneClassTwo替换,这样可以正常工作。

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

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