在Java

时间:2015-07-06 10:31:18

标签: java generics

根据Java关于Type ErasureBounded Type Parameters的文档,我理解在下面的代码示例中,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) {
  }
}

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

  

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

因此,我应该能够应用一个绑定然后它会编译,因为现在类型擦除版本的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)具有相同的擦除

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

1 个答案:

答案 0 :(得分:8)

问题是,在您的两种方法中,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替换,效果很好。