2012-04-19 65 views
7

Giả sử tôi có một phương pháp đơn giản như thế này để xử lý hai danh sách:Java Generics: Suy luận kiểu trên hai tham số

public static <B> void foo(List<B> list1, List<B> list2) { 
} 

Và giả sử tôi muốn gọi nó như thế này:

foo(ImmutableList.of(), ImmutableList.of(1)); 

won này Không biên dịch, bởi vì javac không đủ thông minh để tìm ra tôi đang cố tạo hai danh sách Số nguyên. Thay vào đó, tôi phải viết:

foo(ImmutableList.<Integer>of(), ImmutableList.of(1)); 

Làm cách nào để thay đổi cách khai báo foo để cho phép phiên bản đầu tiên hoạt động cũng như phiên bản thứ hai?

+1

Khá chắc là không thể thực hiện bằng cách thay đổi khai báo 'foo()'. –

+0

Trên thực tế, nó không phải là vấn đề của 'javac' không đủ thông minh, đó là câu hỏi thực sự về ý nghĩa của bạn bởi' ImmutableList.of() '. Điều gì xảy ra nếu 'of()' trả về không phải là một danh sách trống nhưng một danh sách chứa đầy 5 đối tượng được tạo với các hàm tạo mặc định? Nó chỉ là nội bộ của 'of()' cho bạn biết đó không phải là trường hợp, và nếu đó là những gì đã xảy ra thì 'foo' sẽ nhận được một danh sách' Object 'và một danh sách' Integer '. –

Trả lời

3

Tôi khá chắc rằng suy luận kiểu Java không đủ mạnh để xử lý sự hợp nhất.

gì bạn có thể làm là trả về một đối tượng trung gian của một số loại, và thay đổi trang web gọi là cái gì đó như:

foo(list1).and(list2) 

Nhưng sau đó nó sẽ vẫn chỉ có thể suy ra từ trái sang phải, vì vậy bạn phải gọi nó là:

foo(ImmutableList.of(1)).and(ImmutableList.of()); 
1

bạn có thể làm điều đó bằng cách đơn giản thay đổi thông tin chung của paramter và cả hai phiên bản sẽ work.ie

public static <B> void foo(List<? super B> list1, List<B> list2) { 


     } 

Hiện tại Cả hai phiên bản sẽ hoạt động.

foo(ImmutableList.of(), ImmutableList.of(1)); 
foo(ImmutableList.<Integer>of(), ImmutableList.of(1)); 
+1

Đây không phải là một lựa chọn tuyệt vời nếu 'foo' thực sự đọc' B 'từ' list1'. – trutheality

2

Cài đặt duy nhất mà tôi cho rằng đây là bất tiện cho bạn là khi bạn làm điều này rất nhiều. Trong trường hợp đó, bạn có thể tạo

private static final ImmutableList<Integer> EMPTYINTLIST = ImmutableList.<Integer>of(); 

và sử dụng EMPTYINTLIST trong các cuộc gọi của bạn.

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