Implications for Overloading
Given the definitions above, we can now state that two methods are overloaded if they have the same name, but their signatures are not override-equivalent. Given the following three generic method declarations in a class:
static <T> void merge(MyStack<T> s1, MyStack<T> s2) { /*…*/ }
static <T> void merge(MyStack<T> s1, MyStack<? extends T> s2) { /*…*/ }
static <T> void merge(MyStack<T> s1, MyStack<? super T> s2) { /*…*/ }
After erasure, the signature of all three methods is:
merge(MyStack, MyStack)
That is, the signatures of the methods are override-equivalent, hence these methods are not overloaded. A class cannot contain two methods with override-equivalent signatures, and the compiler will report an error.
These three methods:
static <T> void merge(Node<T> s1, MyStack<T> s2) { /*…*/ }
static <T> void merge(MyStack<T> s1, MyStack<? extends T> s2) { /*…*/ }
static <T> void merge(MyStack<T> s1, Node<? super T> s2) { /*…*/ }
have the following signatures after erasure, respectively:
merge(Node, MyStack)
merge(MyStack, MyStack)
merge(MyStack, Node)
We can see that no two signatures are override-equivalent. Therefore, the three methods are overloaded.
The declaration of the class MethodSGN below shows some variations on the method signature. The resulting signature of the method header (which includes the method signature) is shown after erasure in the comment corresponding to the method.
class MethodSGN<T> {
void doIt(boolean b) {} // (1) void doIt(boolean)
void doIt(T t) {} // (2) void doIt(Object)
List<StringBuilder> doIt(StringBuilder sb) { // (3) List doIt(StringBuilder)
return null;
}
<E extends Comparable<E>> void doIt(E element) // (4) void doIt(Comparable)
{}
<E> E doIt(MyStack<? extends E> stack) { // (5) Object doIt(MyStack)
return null;
}
}
Adding any of the method declarations given below to the class MethodSGN would be an error, as each one of these method declarations has a method signature that is the same as one of the methods already in the class—that is, the signatures are override-equivalent.
void doIt(Object obj) {} // (2′) void doIt(Object)
<E extends StringBuilder> List<E> doIt(E sb) { // (3′) List doIt(StringBuilder)
return null;
}
void doIt(Comparable<T> element) {} // (4′) void doIt(Comparable)
<E> E doIt(MyStack<? super E> stack) { // (5′) Object doIt(MyStack)
return null;
}
Leave a Reply