Ví dụ, foo()
là không an toàn, nó có thể lưu trữ không-T trong mảng, gây ra vấn đề tại [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]
}
Bằng cách đánh dấu các phương pháp với @SafeVarargs, bạn hứa sẽ biên dịch hai người là bạn không làm gì nghịch ngợm như thế.
Nhưng làm cách nào để chúng tôi có thể nhận được một mảng chung tại [1] để bắt đầu? Java không cho phép tạo mảng chung!
Cách duy nhất bị xử phạt sáng tạo mảng chung là khi gọi một phương pháp vararg
foo(list_int_1, list_int_2)
sau đó mảng không thể truy cập để người gọi, người gọi không thể làm [2] dù sao, nó không quan trọng cách foo()
gây rối với mảng.
Nhưng sau đó bạn nghĩ về nó, nó là backdoor để tạo mảng chung
@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
return Arrays.copyOf(array, length);
}
List<String>[] array1 = newArray(10);
và mảng generic đen
@SafeVarargs
static <E> E[] array(E... array)
{
return array;
}
List<String>[] array2 = array(list1, list2);
Vì vậy, chúng tôi thể tạo mảng chung sau khi tất cả. .. Silly Java, cố gắng ngăn cản chúng ta làm điều đó.
Bạn có thể tạo mảng chung mà không có phương pháp varargs, nhưng bạn phải sử dụng [Array # newInstance (Loại > loại, độ dài int)] (http://tinyurl.com/3uzbb7v) và truyền nó. Cảm ơn câu trả lời kỹ lưỡng. – Jeffrey
Không thực sự là một "đơn giản hóa", mà là một gợi ý cải tiến. –
Tôi đang cố gắng ví dụ này và tôi thấy không có thay đổi về hành vi có và không sử dụng @SafeVarargs. Tôi vẫn nhận được cảnh báo "Loại an toàn: Một mảng chung của Danh sách ...." –
excalibur