Implications for Overloading – Generics

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:

Click here to view code image

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:

Click here to view code image

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.

Click here to view code image

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.

Click here to view code image

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;
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *