2013-06-08 23 views
8

tôi sử dụng Generics trong Java nhưng nó không phải là quá tốt như tôi nghĩBộ sưu tập an toàn hơn danh sách tiêu chuẩn với loại chung?

public static void add(List l, Object o) { 
    l.add(o); 
} 

public static void main(String[] args) throws Exception { 
    List<Integer> list = new ArrayList<Integer>(); 
    add(list, "1.23"); 
    add(list, 1.23); 
    System.out.println(list); 
} 

Tất cả điều này biên dịch và làm việc. Khi tôi nhận được một giá trị từ list một ngoại lệ được ném.

Nó có thể an toàn hơn trong Java 6 không?

+3

Tại sao bạn không sử dụng phương thức 'list.add()'? Khai báo phương thức 'add()' của bạn với tham số 'List ' chung. – NINCOMPOOP

+0

Tôi hiểu, nhưng tôi phải đối mặt với loại tẩy xoá (mã cũ) –

+0

@KalamarObliwy: Nhưng nó sẽ giúp bạn tiết kiệm từ các lỗi thời gian biên dịch và do đó sẽ lưu từ 'ClassCastExceptions' vào thời gian chạy. – NINCOMPOOP

Trả lời

14

tôi đề nghị sử dụng các tiêu chuẩn Collections:

List<Integer> checked = Collections.checkedList(list, Integer.class); 

sau đó chỉ cần làm việc trên checked. Một ClassCastException sẽ được ném trong khi chèn bất kỳ cá thể không tuân thủ nào - sớm hơn (do đó tốt hơn) so với trước đây (tức là trong quá trình truy xuất).

N.B. kiểm tra thông điệp trình biên dịch của bạn, tôi đặt cược bạn có một số cảnh báo in trong đó đề cập đến mã không an toàn/không được kiểm soát .. Vấn đề của bạn là chính xác những gì trình biên dịch đang cố gắng cho bạn biết. Nếu bạn kiểm soát chữ ký của add, làm cho nó chung chung - nó sẽ cung cấp cho bạn an toàn biên dịch-thời gian.

public static <T> void add(List<T> list, T t) { 
    list.add(t); 
} 
+0

+1 cho đề xuất 'Collections.checkedList()'. Tuy nhiên, 'add()' nên cho phép các kiểu con của kiểu khai báo được chèn vào, để nếu danh sách được khai báo là 'List ' trình biên dịch sẽ cho phép bất cứ thứ gì được thêm vào. Do đó, 'Danh sách ' sẽ phù hợp hơn 'Danh sách '. –

+0

Nếu OP có kế hoạch ** chỉ thêm ** vào 'danh sách', thì bạn hoàn toàn đúng. Tôi đã suy nghĩ tổng quát hơn. – emesx

+0

Phương thức 'add()' thường * chỉ thêm * vào danh sách;) nhưng trên suy nghĩ thứ hai, tôi nghĩ * Tôi đã sai * :): vì đó là về tập hợp và phần tử, phần tử sẽ được "thăng cấp" bởi trình biên dịch siêu siêu trong suốt. Những gì tôi nói thực sự chỉ áp dụng cho hai loại chung: 'A ' và 'B ' vì đây là những bất biến. –

3

Tôi không nghĩ vậy. Nếu phương thức tĩnh add() là một thực tế của cuộc sống (điều bạn không kiểm soát), bạn không thể làm được gì nhiều, vì các Generics Java được triển khai để chúng tương thích với Java < 5.0.

Tuy nhiên, nếu bạn có thể thay đổi chữ ký của phương pháp add(), bạn có thể chỉ đơn giản là thực thi việc kiểm tra loại để bạn có được lỗi biên dịch cho các mã trong main() phương pháp của bạn:

public static <T> void add(List<? super T> list, T object) { 
    list.add(object) 
}