Ambiguity Errors in Generics
The inclusion of generics gives rise to another type of error that you must guard against: ambiguity. Ambiguity errors occur when erasure causes two seemingly distinct generic declarations to resolve to the same erased type, causing a conflict. Following is an example that involves method overloading :
Gen declares two generic types: T and V. Inside Gen, an attempt is made to overload set( ) based on parameters of type T and V. This looks reasonable because T and V appear to be different types. But, the problem is that the type erasure of set( ) reduces both versions to the set(Object). Thus, the overloading of set( ) as attempted in Gen is inherently ambiguous.
Ambiguity errors can be tricky to fix. For example, if you know that T will always be some type of Number, you might try to fix Gen class by rewriting its type declaration to Gen<T extends Number, V> :
The T extends Number causes Gen class to compile, and you can even instantiate objects like the one shown following :
The gen1 set( ) methods works perfectly. Because Java can accurately determine which method to call. Consider the following instantiation, ambiguity returns when you call the set( ) method.
In this case, since both T and V are Integer, which version of set( ) is to be called? The call to set( ) is now ambiguous. Frankly, in the preceding example, it would be much better to use two separate method names, rather than trying to overload set( ).
Program
class Gen<T extends Number, V> { T t1; V v1; void set(T t) { t1 = t; } void set(V v) { v1 = v; } } public class Javaapp { public static void main(String[] args) { Gen<Integer, Integer> gen = new Gen<Integer, Integer>(); gen.set(55); } }