简体   繁体   English

T ...(泛型vararg参数)在编译时真的被剥离到Object []吗?

[英]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.) (我将在这里使用T来引用泛型参数,在参数化类中使用。)

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. 我读到当用作参数时T...是潜在的堆污染源的原因是编译器对正常(不允许T[]数组)规则进行例外处理,并允许T... (这是varargs,因此通常会通过varargs规则在内部转换为T[] ,除非通用内容将其作为参数通过在内部实现,就像它是原始类型一样,将其转换为Object[]数组Object[]而不是。

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[] . 我把T...t作为方法的参数,然后是System.out.println t.getClass[] I expected to get the class of Object[] , but instead, I got T[] 's class. 我希望得到Object[]的类,但是我得到了T[]的类。

So, it appears that the compiler is converting T...t to T[] internally, and not to Object[] . 因此,似乎编译器在内部将T...t转换为T[] ,而不是Object[]

eg 例如

 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? 如果编译器没有将泛型varargs参数内部转换为Object[] ,那么它如何失去类型安全性并充当堆污染的潜在来源?

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[] . 所以t的运行时类型是Integer[] ,即使它的声明类型(在编译之后)是Object[]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM