2011-01-28 21 views

Trả lời

19

<typearg>methodname là cú pháp để xác định một cách rõ ràng đối số kiểu cho một generic method

Khi bạn sử dụng một lớp chung, bạn thường phải xác định đối số kiểu (ví dụ String):

ArrayList<String> list = new ArrayList<String>(); 

Với phương pháp chung, bạn thường không vượt qua đối số loại:

public static <T> void foo(T param) { } 
... 
String s = ...; 
MyClass.foo(s); 

Bạn sẽ nhận thấy không có mã nào đã xác định rõ ràng chúng tôi muốn phiên bản String của foo, tức là không có đối số loại rõ ràng <String> được chỉ định như chúng tôi đã thấy khi sử dụng lớp chung (List<String>).

Trình biên dịch đang thực hiện một số phép thuật trình biên dịch để suy ra đối số kiểu chung dựa trên ngữ cảnh. Đây là một điều tuyệt vời và rất mạnh mẽ.

Tuy nhiên, thỉnh thoảng mới trình biên dịch không thể suy ra những lập luận kiểu tự động:

public static <T> void bar() { T myLocalVar = ...; ... } 
MyClass.bar(); 

gì cụ thể phiên bản của bar Chúng ta đang cố gắng để gọi, ví dụ: đối số kiểu cho cuộc gọi này là gì? Dunno? Vâng, trình biên dịch cũng không.Chúng ta phải nói rõ lập luận loại, giống như chúng ta thường làm khi sử dụng một lớp chung:

MyClass.<String>bar(); 

Xem thêm:


Ngoài: nó có thể là đáng nói đến là Java 7 sẽ được bổ sung thêm các nhà điều hành kim cương cái gọi là để cho phép chúng tôi có trình biên dịch để suy ra những lập luận kiểu khi sử dụng các lớp học chung bây giờ quá:

ArrayList<String> list = new ArrayList<String>(); 

trở thành

ArrayList<String> list = new ArrayList<>(); 

What is the point of the diamond operator in Java 7?

8

Đây là cách bạn chỉ định rõ ràng thông số loại cho một phương pháp chung. Trong hầu hết các trường hợp, trình biên dịch có thể suy ra nó, nhưng đôi khi nó cần phải được khai báo rõ ràng.

+0

Vì sự tò mò của riêng tôi - nó có cần phải được khai báo rõ ràng vì các phương pháp đó là tĩnh không? – christophmccann

+1

@Christopher: no. Nó hoạt động cả trong các phương thức tĩnh và không tĩnh. –

+0

Nó cần phải được khai báo rõ ràng vì nó tĩnh, vì vậy không có hàm tạo nào đã sửa các đối số kiểu Generic và vì các đối số kiểu chung không thể được suy ra từ danh sách tham số. –

1

Những câu trả lời ở trên khá nhiều giải quyết câu hỏi của bạn, nhưng nếu bạn muốn có một ví dụ cụ thể của một trường hợp suy luận kiểu generic Java của thất bại và expli citly nêu nó theo cách này tiết kiệm trong ngày, hãy xem xét các định nghĩa lớp sau đây:

public class A { } 
public class B extends A { } 
public class C extends A { } 

Sau đó, đoạn mã sau chỉ hoạt động tốt (ví dụ, suy luận kiểu Java thành công):

List<Class<? extends A>> list = ImmutableList.of(B.class, C.class); 

Nhưng sau , không biên dịch được:

List<Class<? extends A>> list = ImmutableList.of(B.class); 

Đúng vậy; lạ đủ, bởi loại bỏ một tham số, chúng ta nhầm lẫn giữa hệ thống kiểu suy luận, kể từ khi 'hậu duệ chung gần' của B.classC.classA.class, nhưng đối với B.class bởi chính nó, nó chỉ là B.class, mà (do thiếu hiệp phương sai trong Generics Java) không khớp với List<Class<? extends A>>. Trong trường hợp này, bạn không có lựa chọn nào khác để sử dụng:

List<Class<? extends A>> list = ImmutableList.<Class<? extends A>>of(B.class); 

Kể từ B không thực sự mở rộng A, đây biên dịch (và chạy) tốt.

Tôi hy vọng cuộc biểu tình này nhấn mạnh tính hữu dụng của nhà điều hành.

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