Действительно ли T... (параметр generics vararg) разделен на Object[] во время компиляции?


(я буду использовать T для ссылки на общий аргумент, используемый в параметризованном классе.)

Я читал, что причина, по которой T... является потенциальным источником загрязнения кучи при использовании в качестве аргумента, заключается в том, что компилятор делает исключение из правила normal (no T[] arrays allowed) и разрешает T... (который является varargs, и поэтому обычно преобразует правила varargs внутренне в T[], за исключением того, что это не разрешено с помощью generics) в качестве параметра, реализуя его внутренне как хотя это был сырой тип, преобразуя его в массив Object[] вместо этого.

Поэтому я написал некоторый код, чтобы проверить это, чтобы закрепить концепцию в моей памяти.

Я взял T...t в качестве аргумента к методу, а затем System.out.println'd t.getClass[]. Я ожидал получить класс Object[], но вместо этого я получил класс T[].

Таким образом, получается, что компилятор преобразует T...t в T[] внутренне, а не в Object[].

Например

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

 }

Чего мне здесь не хватает? И если бы ... компилятор не преобразует универсальный параметр varargs внутренне в Object[], как он теряет безопасность типа и действует как потенциальный источник загрязнения кучи?

1 7

1 ответ:

void method(T... t)

Преобразуется в

void method(Object[] t)
Итак, то, что вы слышали, верно. но :
Integer a = 1, b = 2, c = 3;
method(a, b, c);

Преобразуется в:

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

Таким образом, тип среды выполнения t является Integer[], хотя его объявленный тип (после компиляции) является Object[].