Действительно ли 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 ответ:
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[]
.