I came across an amazing yet strange issue with Java Varargs methods as illustrated below:
1) we know that the compiler will complain if an attempt is made to overload the method print below:
class VarArgs{
public static void print(int... data){
System.out.println("In Varargs: " + data[0]);
}
public static void print(int[] data){
System.out.println("In Array: " + data[0]*2);
}
public static void main(String args[]){
print(2);
}
}
Since these methods would result in two equivalent signature in the same class, if this was permitted.
2) I override the varargs method with a method which accepts an array as follows:
class SuperVarargs{
public void print(int... data){
System.out.println("In Super (Varargs): " + data[0]);
}
}
class SubVarargs extends SuperVarargs{
public void print(int[] data){
System.out.println("In Sub (Array): " + data[0]*2);
}
}
class VarargsOverrideWithArrayTest {
public static void main(String args[]){
SuperVarargs supervar1 = new SubVarargs(); //(1)
int[] array = {5,2,3};
supervar1.print(array); // Prints: In Sub (Array): 10
SuperVarargs supervar2 = new SubVarargs(); //(2)
supervar2.print(5, 2, 3); // Prints: In Sub (Array): 10
SubVarargs subvar = new SubVarargs(); //(3)
subvar.print(5, 2, 3); // Prints: In Sub (Array): 10 !!!
}
}
And just to add to my surprising, the call at (3) compiles just fine and produce the same results as I commented in the code! I was expecting a compile error at (3), and even my intellij idea confused by this as it underline the call at (3) as an error yet it compiles it and run it with no problem! if I remove the inheritance between sub and super then the compiler complains.
My hunch is that the compiler change the signature of the overriding method to a varargs form in byte code so one can call the method with varargs form, even on an object of the type of subclass. This theory could be proved by crack open the class file and read the generated byte code though.
Any ideas? Can someone let me know what is the magic behind this?