Varargs is syntactic sugar that is translated into an array of this type by the compiler. This means that a method(Type arg...) will become method(Type[] arg) .
In Java, you cannot create arrays of non-recoverable types (types whose type information is lost when erased). Therefore, common varargs, such as printClassVarargs(T ... str) , will be translated to printClassVarargs(Object[] str) , which will actually erase the type information. This is what you observe in your test.
--- EDIT ---
To answer your question (cfr comments) on the difference between printClassVarargs(str) and callPrintClassVarargs(str) , we could take a look at the bytecode of your test class for the necessary hints:
public Test(); Code: 0: aload_0 1: invokespecial #8;
Pay attention to the main number 12, that creates a new line [] of your obj line, which will be used as a parameter for printClassVarargs() and callPrintClassVarargs()
In main # 19, printClassVarargs is called with the created String [] parameter. This causes printClassVarargs know the type of this object at runtime. This type has been saved.
In main # 23, callPrintClassVarargs is called, also with the String [] parameter created. Then, a new array is created on callPrintClassVarargs#1 . This time, type information is not accessible from a type type declaration, so a new object [] is created. String [] is stored in this array and callPrintClassVarargs#8 is passed to printClassVarargs , which should now work with Object [], whose printClassVarargs component is an object.
As you can see, the type of your parameter was erased when passed to the general parameter callPrintClassVarargs(T str) .
QED
maasg source share