Erasing collections of generics and conflicting overloads

I have a fairly central class responsible for some Utility methods. I would like to provide additional overload for a method that 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 pointed out the collection to the smallest common denominator I can expect:

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

It is so good so far that it has saved us the warning of rawtypes, and still is.

I started writing a method header for my overload:

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

This is when eclipse (and then compiling with javac6 via ant) โ€‹โ€‹gave me the following error message:

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

Now that I already had my share of problems with wildcard patterns and their deletions, I tried to fully define things by replacing unrelated wildcards with Object . The error message is still saved.

Now that I understand, the first existing overload should be erased before Collection<Map<Object, Object>> , and the second should be erased before Collection<TeObjectWrapper> .

The only way this can be the same erasure is if TeObjectWrapper implements Map (or extends one of the Map implementation classes), but it is not. This can be seen in the hierarchy of the supertype TeObjectWrapper:

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

Why does the compiler consider erasures the same and how can I make it not think about it?

+6
source share
1 answer

Both of them are erased before public static void removeDuplicated(Collection, Collection) . All parameterization is erased. You will need to give them different names.

From 4.6. Erasure Type :

An erasure type is a mapping [...] to types (which never parameterized types or type variables).

The erasure type also maps the signature of a constructor or signature method that has no parameterized types or variable types .

Erasure means: all common disappears.

(But, as an interesting side, general information is present in the class file . The overload rule is that the specification for Java is not necessary, because it is not technically feasible. It is rather backward compatibility, allowing obsolete non-general classes to override common methods. If source types were removed in a future version of the language, overloads such as this may be allowed.)

+6
source

Source: https://habr.com/ru/post/988325/


All Articles