Java 7中简化的Varargs方法调用

时间:2011-10-22 03:53:19

标签: java generics variadic-functions java-7

在Java 7中,您可以选择放置@SafeVarargs注释来抑制在使用不可重新生成的varargs参数编译方法时获得的警告。 Project Coin的proposal规定,当方法确保只有与varargs参数相同类型的元素存储在varargs数组中时,才应使用注释。

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

1 个答案:

答案 0 :(得分:21)

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

<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,试图阻止我们这样做。