2010-05-20 37 views
5

Duyệt qua Guava thư viện tôi nhìn thấy chữ ký kỳ lạ này trên một phương pháp readlines từ lớp Files:Java lạ generic trở lại loại

public static <T> T readLines(File file, 
          Charset charset, 
          LineProcessor<T> callback) 

tôi biết một chút về Generics trong java, nhưng điều này bối rối tôi.

T kép có nghĩa là gì ở đây? Và tại sao người đầu tiên trong ngoặc nhọn?

CẬP NHẬT: Cảm ơn câu trả lời. Tôi vẫn chưa rõ tại sao tôi nên sử dụng T bên trong dấu ngoặc đơn. Tại sao ví dụ có thể không nó chỉ là:

public static <> T readLines() 

hoặc

pulibc static <K> T readLines() 

Hay cú pháp java dictate rằng bức thư CÙNG phải được sử dụng?

Bây giờ this thậm chí còn wierder:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 

làm thế nào một phương pháp có thể có một kiểu generic-lợi nhuận và không có giá trị?

+0

Dấu T trong ngoặc vuông KHÔNG phải là loại trả về; đó là tham số kiểu cho phương thức. –

+0

Lưu ý rằng nếu không có trong các chữ ký trên, trình biên dịch sẽ tự nhiên mong muốn tìm "lớp T {...}" được định nghĩa ở đâu đó. Một cái gì đó đã thông báo cho trình biên dịch mà bạn muốn có một tham số * loại * được gọi là T. Và đây là cách. –

Trả lời

3

Tôi vẫn chưa rõ tại sao tôi nên sử dụng dấu T bên trong dấu ngoặc vuông. Tại sao ví dụ có thể không nó chỉ là:

public static <> T readLines() 

hoặc

public static <K> T readLines() 

Hay cú pháp java dictate rằng bức thư CÙNG phải được sử dụng?

<T> hoặc <K> là thông số loại. Nếu bạn viết <K> T, thì T không phải là thông số loại - thay vào đó, bạn đang sử dụng class T cụ thể. Điều này sẽ không hoạt động nếu bạn không có một lớp học theo nghĩa đen có tên là T trong phạm vi.

Bây giờ điều này thậm chí còn wierder:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 

làm thế nào một phương pháp có thể có một kiểu generic-lợi nhuận và không có giá trị?

Nó không; <T> không phải là "loại trả về chung", nó chỉ là tham số kiểu cho phương thức. Bạn đang nói rằng phương pháp này là chung chung và T là thông số loại. Kiểu trả về của phương thức là void.

+0

Đây là câu tôi đang tìm kiếm: "Bạn đang nói rằng phương thức này là chung chung, và T là tham số kiểu." Cảm ơn! – drozzy

7

Dấu đầu tiên bên trong dấu ngoặc nhọn có nghĩa là chính phương thức đó là chung. T thứ hai là kiểu trả về. T có thể là bất kỳ loại nào trong giới hạn của nó. Trong trường hợp này, T không có giới hạn.

T sẽ được xác định tại trang web cuộc gọi và trong trường hợp này, được suy ra từ tham số LineProcessor <T>.

9

Đây là phương pháp chung chung - số T được gọi là thông số loại và có thể đại diện cho bất kỳ loại nào. Vì vậy, nếu tôi có một phương pháp có chữ ký này:

public <T> T foo(T[] bar) 

Tôi có thể gọi nó trên bất kỳ mảng nào và nó sẽ trả về một đối tượng duy nhất cùng loại. Nếu tôi vượt qua nó một mảng String, tôi sẽ lấy lại một String, và như vậy. Thông tin thêm in the Sun tutorials for "generic methods".

Edit: Trong câu trả lời cho câu hỏi của bạn được cập nhật, hãy nhớ rằng người đầu tiên <T>không phải là phần của kiểu trả về: nó chỉ là một chỉ báo rằng T là một tham số kiểu. Vì vậy, nhìn vào ví dụ bạn trích dẫn:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) 

Đó chỉ có nghĩa là fromArrayToCollection sẽ chấp nhận bất kỳ mảng và bất kỳ bộ sưu tập, nhưng rằng họ phải là một mảng và tập hợp các loại tương tự. Vì vậy, bạn có thể vượt qua trong một số String[]Collection<String> hoặc Integer[]Collection<Integer>, nhưng không được String[]Collection<Integer>. Không có vấn đề gì loại bạn đưa vào cho T, phương pháp trả về không có gì.

+0

Cảm ơn, hãy xem cập nhật cho câu hỏi của tôi – drozzy

0

Đây là phương pháp chung.

Thực ra có ba Ts, số thứ ba trên LineProcessor<T> chỉ định T khi bạn sử dụng phương pháp.

3

Thay vì chỉ chung chung ở cấp lớp, chỉ có phương thức readLines sử dụng Generics.

  • Các <T> đầu tiên tuyên bố các loại chung được sử dụng theo phương pháp
  • T Sau đây là kiểu trả về.

Cách đầu tiên sử dụng cú pháp giống như một lớp chung để khai báo các loại chung. Thay vào đó, bạn có thể viết

class Generic <T> 
{ 
public static T readLines(File file, 
          Charset charset, 
          LineProcessor<T> callback) 
} 

Tuy nhiên, điều này sẽ làm cho tất cả các trường hợp của lớp chung chung.

Extended Ví dụ:

public static <ElementType,ListType extends List<ElementType>> ListType add(ListType list,ElementType elem) 
{ 
    list.add(elem); 
    return list; 
} 
ArrayList<String> = add(add(new ArrayList<String>(),"Hello"),"World"); 

Phương pháp này cho biết thêm một phần tử trao cho một danh sách và trả về danh sách.
Phương pháp này sử dụng hai loại chung cho một trong các thành phần của danh sách và một cho chính danh sách đó.
Các tên được sử dụng không có gì đặc biệt, sử dụng T cho kiểu chung giống như sử dụng i cho một số nguyên.

  • elementType là tên được sử dụng cho các loại chung của các yếu tố (bất kỳ tên biến/định danh hợp lệ có thể được sử dụng)
  • ListType là tên Type danh sách chung, các lớp sử dụng phải mở rộng/triển khai Danh sách cho ElementType.

Ví dụ gọi phương thức với:

  • elementType = Chuỗi
  • ListType = ArrayList

mà sẽ cho kết quả trong
public static ArrayList<String> add(ArrayList<String> list, String elem)

Bloat cuối :-)

+0

Cảm ơn, điều này làm cho nó rõ ràng hơn ... nhưng tại sao tôi phải sử dụng chữ "T" bên trong dấu ngoặc như trái ngược với chữ "K" hoặc "B" hoặc không tất cả (nghĩa là chỉ các dấu ngoặc đơn trống). – drozzy

+0

Chữ T chỉ là một cái tên, tên giữa < and > chỉ khai báo tên cho các loại chung được sử dụng. Bạn có thể khai báo một phương thức với 3 kiểu generic như public ExtraType someMethod (TypeA var1, AnOtherTypeB var2, ExtraType var3). – josefx

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