2009-07-07 34 views
5

tôi thấy một chức năng java trông giống như this-Java: Điều gì là - public static <T> foo() {...}?

public static<T> foo() {...} 

Tôi biết những gì Generics nhưng ai đó có thể giải thích trong bối cảnh này? Ai quyết định T là gì? Những gì đang xảy ra ở đây?

EDIT: Ai đó có thể vui lòng cho tôi xem ví dụ về chức năng như thế này không.

+0

Ý của bạn là: public static int binarySearch (Danh sách > danh sách, khóa T) trong Bộ sưu tập? Nó chỉ là một kiểu generic, trong trường hợp này nếu khóa của bạn là một String, thì Danh sách của bạn phải là các phần tử thực hiện Comparable có thể so sánh Strings. Không có gì quyết định những gì T bằng, nó chỉ là kiểm tra thời gian biên dịch. – JeeBee

+0

Vâng đó là ý tôi. – quilby

Trả lời

11

Bạn đã bỏ lỡ kiểu trả về, nhưng ngoài ra đó là một phương thức chung chung. Giống như các loại chung, T là viết tắt của bất kỳ loại tham chiếu nào (trong giới hạn nếu được cung cấp).

Đối với các phương pháp, thông số chung thường được trình biên dịch suy ra. Trong những tình huống nhất định bạn có thể muốn chỉ định các đối generic chính mình, bằng cách sử dụng cú pháp hơi khác thường:

List<String> strings = Collections.<String>emptyList(); 

Trong trường hợp này, trình biên dịch có thể đã suy ra các loại, nhưng nó không phải luôn luôn rõ ràng cho dù trình biên dịch có thể hoặc có thể' t. Lưu ý, <> là sau dấu chấm. Vì lý do cú pháp, tên của kiểu hoặc đối tượng đích phải luôn được xác định.

Có thể có các nhà xây dựng chung, nhưng tôi chưa bao giờ thấy một nhà khai thác hoang dã và cú pháp trở nên tồi tệ hơn.

Tôi tin rằng cú pháp C++ và C# đặt các loại chung sau tên phương thức/hàm.

+0

Agh! Đôi mắt của tôi! Nó cháy! – skaffman

+0

bạn đá. Kìa, guru java thực sự!/cúi xuống /: D – jrharshath

0

T là thông số loại hình chính thức sẽ được thay thế bằng loại đối số thực tế được sử dụng tại phiên bản của đối tượng.

Ví dụ, đây là danh sách và Iterator definitios trong gói java.util:

public interface List<E>{ 
    void add(E x); 
    Iterator<E> iterator(); 
} 

public interface Iterator<E>{ 
    E next(); 
    boolean hasNext(); 
} 

Sau đó, bạn có thể nhanh chóng một danh sách theo cách này:

List<String> ls = new ArrayList<String>() 

Nơi bạn có thể tưởng tượng rằng Danh sách gian hàng đối với phiên bản Danh sách trong đó E có được thay thế đồng nhất bằng Chuỗi:

public interface StringList{ 
    void add(String x) 
    Iterator<String> iterator(); 
} 
+0

Không nhất thiết phải bất kỳ đối tượng nào được khởi tạo. (Sử dụng một dự đoán hợp lý về những gì mà ví dụ nên có.) –

+0

Hhmm .. bạn nói đúng, người thay thế được thực hiện tại thời gian _compilation_ (nhưng dù sao, điều này sẽ được sử dụng để khởi tạo đối tượng sau) –

+0

Không cần bất kỳ sự khởi tạo đối tượng nào đang diễn ra. Cú pháp xuất hiện cho các phương thức chung chung, không phải là các kiểu generic. (Về mặt kỹ thuật, ví dụ của người hỏi cần có một sự thay thế để nhận được một cú pháp hợp lệ có thể là 'public foo() {...} 'là cú pháp hợp lệ về mặt kỹ thuật cho một lớp có tên' foo' (hoặc trình biên dịch không phàn nàn về việc không sử dụng thông số chung?).) –

2

Ngữ cảnh là một phương thức chung chung trái ngược với một lớp. Biến số <T> chỉ áp dụng cho cuộc gọi của phương thức .. Lớp sưu tập có một số trong số này; bản thân lớp không phải là chung chung, nhưng nhiều phương thức là.

Trình biên dịch quyết định nội dung T bằng - nó bằng bất kỳ thứ gì có được các loại hoạt động. Đôi khi điều này dễ dàng hơn những người khác.

Ví dụ, phương pháp static <T> Set<T> Collections.singleton(T o) loại được xác định trong tham số:

Collections.singleton(String T) 

sẽ trả về một Set<String>.

Đôi khi loại khó xác định. Ví dụ đôi khi không có đủ thông tin để nhập Collection.emptyList(). Trong trường hợp đó, bạn có thể chỉ định loại trực tiếp: Collection.<String>emptyList().

+0

Vui lòng xem chỉnh sửa của tôi – quilby

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