Ambiguity
Errors
The inclusion of generics
gives rise to a new 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. Here is an example that involves method overloading:
// Ambiguity caused by erasure on overloaded
methods.
class MyGenClass<T, V> { T ob1;
V ob2;
//These two overloaded methods are ambiguous and
will not compile.
void set(T o) { ob1 = o;
}
void set(V o) { ob2 = o;
}
}
Notice that MyGenClass declares two generic types: T and V. Inside MyGenClass, 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. However, there are two ambiguity
problems here.
First, as MyGenClass is written, there is no
requirement that T and V actually be different types. For
example, it is perfectly correct (in principle) to construct a MyGenClass object as shown here:
MyGenClass<String, String> obj = new
MyGenClass<String, String>()
In this case, both T and V will be replaced by String.
This makes both versions of set( )
identical, which is, of course, an error.
The second and more
fundamental problem is that the type erasure of set( ) reduces both versions to the following:
void set(Object o) { // ...
Thus, the overloading of set( ) as attempted in MyGenClass is inherently ambiguous.
Ambiguity errors can be tricky to fix. For example, if you know that V will always be
some type of Number, you might try to fix MyGenClass by rewriting its declaration
as shown here:
class MyGenClass<T, V extends Number> {
// almost OK!
This change causes MyGenClass to compile, and you can even
instantiate objects like the one shown here:
MyGenClass<String, Number> x = new
MyGenClass<String, Number>();
This works because Java can
accurately determine which method to call. However, ambiguity returns when you
try this line:
MyGenClass<Number, Number> x = new
MyGenClass<Number, Number>();
In this case, since both T and V are Number, 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( ). Often,
the solution to ambiguity involves the restructuring of the code, because
ambiguity frequently means that you have a conceptual error in your design.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.