2013-02-22 52 views
10

Tôi vẫn đang học về generics và có một câu hỏi. Giả sử bạn có lớp học chung này:Sự khác biệt giữa các câu lệnh này trong một lớp học chung là gì?

public class Test<T> { 

    public static void main (String[] args) { 
     Test t1 = new Test(); 
     Test<String> t2 = new Test<String>(); 
     Test t3 = new Test<String>(); 
    } 
} 

Tất cả các câu lệnh biên dịch nhưng tôi thực sự không biết điều gì làm cho chúng khác biệt. Bất cứ ai có thể cho tôi một lời giải thích ngắn gọn về ba phát biểu đó.

+0

Hầu như thật. Hai cảnh báo quảng cáo duy nhất khác, nhưng không phải là lỗi biên dịch thực. –

Trả lời

9
Test t1 = new Test(); 

Ở đây bạn đang sử dụng Loại thô. tức là, không vượt qua Type argument cho số generic clas của bạn.

trình biên dịch sẽ cung cấp cho bạn một cảnh báo ở đây

thử nghiệm là một loại nguyên liệu. Tài liệu tham khảo để loại thử nghiệm chung chung nên tham số

Test<String> t2 = new Test<String>(); 

đây bạn đang sử dụng Generics. chuyển chuỗi dưới dạng type argument tới số generic class của bạn.

Test t3 = new Test<String>(); 

trình biên dịch cũng nên cung cấp cho bạn một cảnh báo ở đây quá:

  • thử nghiệm là một loại nguyên liệu. Tài liệu tham khảo để loại thử nghiệm chung chung nên được tham số

tương tự như trường hợp đầu tiên của bạn, nhưng bạn đang sử dụng kiểu tham số khi gọi các nhà xây dựng.

Ngoài ra còn có một lớp khác hoạt động tốt trong phiên bản + java 7.

Test<String> t4 = new Test<>(); 

Không biên dịch cảnh báo ở đây nếu bạn sử dụng + java 7 do suy luận kiểu

Trong trường hợp này do giới thiệu type inference loại generic được suy ra, do đó bạn không cần phải cung cấp generic loại trong quá trình khởi tạo hàm tạo.

+1

Chúng ta cũng nên thêm rằng câu hỏi ban đầu bỏ lỡ hai kết hợp: 'Test t4 = new Test()', sẽ không biên dịch vì nó cố gán một tham chiếu của kiểu thô cho một kiểu chung; và 'Thử nghiệm t5 = Thử nghiệm mới <>()', biên dịch bằng cách sử dụng toán tử "kim cương" mới trong Java 7. – yshavit

+1

+1 và vì java 7 bạn cũng có thể viết Test t4 = new Test <>(); tương đương với khai báo t2 ... – pgras

+1

@yshavit và pgras vừa thêm nó :) – PermGenError

2

Tất cả chúng thực sự tạo các đối tượng giống hệt nhau. Sự khác biệt duy nhất sẽ là cách chúng được xử lý cú pháp trong phần còn lại của mã.

t1t3 sẽ được xử lý theo cùng một cách vì chúng cùng loại - chúng sẽ được coi là đối tượng có lớp Test, không có gì khác.

t2 sẽ được xử lý nghiêm ngặt hơn về kiểm tra loại. Nếu một số cơ hội trình bày chính nó cho trình biên dịch để sử dụng chất lượng chung của nó <String> thì chất lượng đó cũng sẽ được yêu cầu để phù hợp.

3

Generics cung cấp cho bạn kiểm tra loại biên dịch theo thời gian.

Nó giúp để thêm ví dụ về những gì bạn có thể/không thể làm với các mục của bạn (Tôi đã thay đổi Test-ArrayList để dễ ví dụ):

ArrayList t1 = new ArrayList(); 
    ArrayList<String> t2 = new ArrayList(); 
    ArrayList t3 = new ArrayList<String>(); 

    // First list can have ANYTHING added to it 
    // Compiler won't check because no generics 
    t1.add(new Integer("7")); 
    t1.add("Hello"); 

    // Second list can only have Strings added to it 
    // Compiler will check and throw compile error for anything else 
    t2.add(new Integer("7")); // doesn't compile 
    t2.add("Hello"); 

    // Third list is interesting... 
    // Again, can have ANYTHING added to it 
    // This is because generics (in Java...) are swapped out at COMPILE time 
    // rather than RUNTIME. The compiler can see that the actual type is just 
    // plain ArrayList 
    // If you like, it's similar to doing: 
    // Object o = (String) new Object(); 
    // The net-effect is everything reduced back to Object 
    t3.add(new Integer("7")); // fine 
    t3.add("Hello"); 
Các vấn đề liên quan