2011-10-22 48 views
15

Trong Java 7, bạn có tùy chọn để đặt chú thích @SafeVarargs để chặn cảnh báo bạn nhận được khi biên dịch phương thức có tham số varargs không thể tái tạo. Project Coin's proposal quy định rằng chú thích nên được sử dụng khi phương thức này đảm bảo rằng chỉ các phần tử có cùng loại với tham số varargs được lưu trữ trong mảng varargs.Gọi phương thức Varargs đơn giản hóa trong Java 7

Ví dụ về phương pháp không an toàn là gì?

Trả lời

21

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ó 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 đó.

+1

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

+0

Không thực sự là một "đơn giản hóa", mà là một gợi ý cải tiến. –

+0

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

Các vấn đề liên quan