我正在为一个类定义一个构造函数,我有这两个定义:
MyClass(Set<ClassA> setOfA) { ... }
MyClass(Set<ClassB> setOfB) { ... }
我收到以下错误:
MyClass(java.util.Set<ClassA>) is already defined in MyClass
MyClass(Set<ClassB> setOfB)
如果我特意将其中一个设为HashSet而不是Set,则代码会编译。为什么呢?
答案 0 :(得分:7)
如果你有
MyClass(Set<A> setOfA) { ... }
MyClass(Set<B> setOfB) { ... }
类型擦除将它们转换为:
MyClass(Set setOfA) { ... }
MyClass(Set setOfB) { ... }
所以现在他们是一样的,编译器很困惑。
但是,如果其中一个是HashSet
,那么你最终会得到这个:
MyClass(Set setOfA) { ... }
MyClass(HashSet setOfB) { ... }
现在它们与编译器完全不同,以确定在编译时绑定哪个。
答案 1 :(得分:5)
由于 type erasure ,Java编译器将(根据Java文档):
- 将泛型类型中的所有类型参数替换为其边界,如果类型参数无界,则替换
Object
...- 如有必要,插入类型转换以保护类型安全。
- 生成桥接方法以保留扩展泛型类型中的多态性。
换句话说,Java编译器将convert the code to:
MyClass(Set setOfA) { ... }
MyClass(Set setOfB) { ... }
所以两者都有相同的参数。这是导致错误的原因。
答案 2 :(得分:3)
这里的问题是所谓的&#34;类型擦除&#34;。简而言之,这意味着在编译代码后,泛型类型实际上并不存在,因此您的两个构造函数签名MyClass(Set<A>)
和MyClass(Set<B>)
都看起来像MyClass(Set
)。
可以在此处找到Oracle的相关说明:http://docs.oracle.com/javase/tutorial/java/generics/erasure.html