Java 7 中简化的 Varargs 方法调用

2022-09-02 21:19:16

在 Java 7 中,您可以选择放置一个注释来抑制在编译具有不可 reifiable varargs 参数的方法时收到的警告。Project Coin的提案规定,当该方法确保只有与varargs参数相同类型的元素存储在varargs数组中时,应使用注释。@SafeVarargs

什么是非安全方法的示例?


答案 1

例如,不安全,它可能将非 T 存储在数组中,导致 [2] 处出现问题foo()

<T extends List<?>> void foo(T... args)
{
    List<String>[] array2 = (List<String>[])args;
    array2[0] = a_list_of_string;
}

void test2()
{
    List<Integer>[] args = ...;   // [1]
    foo(args);
    Integer i = args[0].get(0);   // [2]
}

通过用@SafeVarargs标记该方法,您可以向编译器保证您不会做任何像那样顽皮的事情。


但是,在地狱中,我们如何才能从[1]开始一个通用数组呢?Java 不允许创建通用数组!

创建泛型数组的唯一受制裁的方式是在调用 vararg 方法时

foo( list_int_1, list_int_2 )

那么数组就不能被调用者访问,调用方无论如何都不能做[2],不管数组如何混乱。foo()

但是你再想想,它是创建泛型数组的后门

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}

List<String>[] array1 = newArray(10);

和泛型数组文本

@SafeVarargs
static <E> E[] array(E... array)
{
    return array;
}

List<String>[] array2 = array( list1, list2 );

因此,我们毕竟可以创建泛型数组...愚蠢的Java,试图阻止我们这样做。


答案 2