简体   繁体   中英

Why can't I define these two constructors in Java for a single class?

I am defining a constructor for a class, and I have these two definitions:

MyClass(Set<ClassA> setOfA) { ... }

MyClass(Set<ClassB> setOfB) { ... }

I get the following error:

MyClass(java.util.Set<ClassA>) is already defined in MyClass
    MyClass(Set<ClassB> setOfB)

If I specifically made one of them a HashSet instead of a Set, the code compiles. Why?

If you have

MyClass(Set<A> setOfA) { ... }

MyClass(Set<B> setOfB) { ... }

Type erasure turns them into:

MyClass(Set setOfA) { ... }

MyClass(Set setOfB) { ... }

So now they're the same, and the compiler is confused.

However, if one of them were a HashSet , you end up with this:

MyClass(Set setOfA) { ... }

MyClass(HashSet setOfB) { ... }

And now they're sufficiently different for the compiler to determine which to bind at compile time.

Because of type erasure , the Java compiler will (according to Java docs):

  • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded...
  • Insert type casts if necessary to preserve type safety.
  • Generate bridge methods to preserve polymorphism in extended generic types.

In other words, the Java compiler will convert the code to :

MyClass(Set setOfA) { ... }

MyClass(Set setOfB) { ... }

so both will have the same parameters. That's the cause of the error.

The problem here is what is called "type erasure". Boiled down, this means that generic types don't actually exist once the code is compiled, so your two constructor signatures MyClass(Set<A>) and MyClass(Set<B>) both look like MyClass(Set ).

The relevant description from Oracle can be found here: http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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