public class Test { public static void print(short a) { System.out.println("short arg: " + a); } public static void print(int a) { System.out.println("int arg: " + a); } public static void print(long a) { System.out.println("long arg: " + a); } public static void print(double a) { System.out.println("double arg: " + a); } public static void main(String[] args) { print(100); // int arg: 100 }}
Type Erasure
If the overloading/overriding methods have same type erasure, then it is not possible to overload/override them
T (without upper bound) effectively changes to Object
public class OverloadingErrors<T extends Serializable> { // Type erasure causes T to replace with upper bound: Serializable public void printElement(T t) { System.out.println("Signature is: printElement(T)"); } // causes compile time error during static binding public void printElement(Serializable o) { System.out.println("Signature is: printElement(Serializable)"); }}
Subclass and Superclass
obj.sum(Integer.valueOf(2), Integer.valueOf(3))
matches with sum(Integer, Integer)
obj.sum(2, 3)
No exact match found
auto boxes int to Integer
matches sum(Integer, Integer)
obj.sum(2, 0x1)
No exact match found
Type promotion from byte value to int and then auto-boxes to Integer
matches sum(Integer, Integer)
obj.sum(2.0d, 3.0d)
No exact match found
double auto-boxes to Double
Double is closest to Number compared to Object
matches sum(Number, Number)
obj.sum(Float.valueOf(2), Float.valueOf(3))
No exact match found
Float is closest to Number compared to Object
matches sum(Number, Number)
public Number sum(Integer term1, Integer term2) { System.out.println("Adding integers"); return term1 + term2;}public Number sum(Number term1, Number term2) { System.out.println("Adding numbers"); return term1.doubleValue() + term2.doubleValue();}public Number sum(Object term1, Object term2) { System.out.println("Adding objects"); return term1.hashCode() + term2.hashCode();}
Varargs
obj.sum(1, 2)
matches sum(Integer, Integer)
obj.sum(1, 2, 3)
matches sum(Integer, Integer...)
obj.sum(1, new Integer[] {2})
matches sum(Integer, Integer...)
public Integer sum(Integer term1, Integer term2) { // ...}// effective signature is sum(Object, Object[])public Integer sum(Integer term1, Integer... term2) { // ...}// causes compile time error // since sum(Object, Object[]) is already presentpublic Integer sum(Integer term1, Integer[] term2) { // ...}