The reason is type erasure. Generics are not stored in the classes, they are compile-time info only, so at runtime, the two methods are identical and hence there is a naming conflict.
Reference
- Generics section of the Sun Java
Tutorial
- Java Generics and Collections
(Book)
These three methods are actually identical (read: they produce identical bytecode):
public static void a(Set plainSet) {}
public static void a(Set<String> stringSet) {}
public static void a(Set<Map<String,String>> mapSet) {}
If you really want to have two separate methods, you must provide different method signatures (e.g. different method names, an additional parameter for one of the methods etc.)