Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is T... (generics vararg parameter) really stripped down to Object[] at compile time?

(I'll use T to refer to a generic argument here, used in a parameterized class.)

I read that the reason that T... is a potential source of heap pollution when used as an argument is that the compiler is making an exception to the normal (no T[] arrays allowed) rule, and allowing T... (which is varargs, and so would normally translate by varargs rules internally to T[], except that this isn't allowed with generics) as a parameter by implementing it internally as though it were a raw type, converting it to an array of Object[] instead.

So I wrote some code to verify this, to cement the concept into my memory.

I took T...t as an argument to a method, and then System.out.println'd t.getClass[]. I expected to get the class of Object[], but instead, I got T[]'s class.

So, it appears that the compiler is converting T...t to T[] internally, and not to Object[].

e.g.

 public class MyClass<T>{
 public void method(T...t)
 {
    System.out.println(t.getClass().getName());  //for MyClass<String>, this gives me  
                                                 //[Ljava.lang.String

 }

What am I missing here? And if the compiler's not converting the generic varargs parameter internally to Object[], how is it losing type safety and acting as a potential source of heap pollution?

like image 531
Mer Avatar asked Sep 04 '14 00:09

Mer


People also ask

What happens at compile time with generic types?

Generics are checked at compile-time for type-correctness. The generic type information is then removed in a process called type erasure. For example, List<Integer> will be converted to the non-generic type List , which ordinarily contains arbitrary objects.

Do generics provide compile time safety?

Generics also provide compile-time type safety that allows programmers to catch invalid types at compile time.

What is generics type parameter?

Generic Methods A type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.

Are Java generics capable of preventing runtime error?

There are many advantages of using generics in Java. Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.


1 Answers

void method(T... t)

gets converted to

void method(Object[] t)

so what you have heard is correct. But:

Integer a = 1, b = 2, c = 3;
method(a, b, c);

gets converted into:

Integer a = 1, b = 2, c = 3;
method(new Integer[] {a, b, c});

so the runtime type of t is Integer[], even though its declared type (after compilation) is Object[].

like image 52
user253751 Avatar answered Nov 13 '22 00:11

user253751