Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erasing Collections generics and conflicting overloads

I have a rather central class responsible for some Utility methods. I wanted to provide an additional overload for a method which was declared as follows:

public static void removeDuplicated(Collection fullList, Collection itemsToRemove) {
   //implementation stripped for brevity
}

Now since I don't really like Rawtypes, I specified the collections out into the least common denominator I can expect:

public static void removeDuplicated(Collection<Map<?,?>> fullList,
     Collection<Map<?,?>> itemsToRemove) {}

So far so good, this got rid of the rawtypes warning and everthing's fine up to now.

I proceeded to write the method header for my overload:

public static <T extends TeObjectWrapper> void removeDuplicated(
     Collection<T> fullList, Collection<Map<?,?>> itemsToRemove) {}

This is when eclipse (and subsequently compiling with javac6 via ant) gave me following error-message:

Erasure of method removeDuplicated(Collection<T>, Collection<? extends Map<?,?>>) is the same as another method in type [Utilites-Class]

Now since I already had my share of problems with wildcard generics and their erasures I tried to specify things out completely, by replacing the unbound wildcards with Object. The error message still persists.

Now from how I understand it, the first existing overload should erase to Collection<Map<Object, Object>> and the second one should erase to Collection<TeObjectWrapper>.

The only way these could be the same erasure is, if TeObjectWrapper implemented Map (or extended one of the Implementing classes of Map), but this is not the case. That can be seen in the supertype hierarchy of TeObjectWrapper:

Supertype hierarchy: -TeObjectWrapper extends Object, implements <TeObjectAbstract implements TeBaseAbstract>

Why does the compiler consider the erasures the same and how can I make him not think that?

like image 642
Vogel612 Avatar asked Jun 01 '15 14:06

Vogel612


1 Answers

Both of them erase to public static void removeDuplicated(Collection, Collection). The entire parameterization is erased. You will need to give them different names.

From 4.6. Type Erasure:

Type erasure is a mapping [...] to types (that are never parameterized types or type variables).

Type erasure also maps the signature of a constructor or method to a signature that has no parameterized types or type variables.

Erasure means: everything generic disappears.

(But, as an interesting side-note, the generic information is present in the class file. The overload rule is due to the way the spec for Java is given, not necessarily because it's not technically feasible. It's more of a backwards compatibility thing, to allow legacy non-generic classes to override generic methods. If raw types were removed in a future version of the language, overloads like this could be allowed.)

like image 164
Radiodef Avatar answered Sep 22 '22 17:09

Radiodef