2016-03-15 23 views
7

Tôi đang chuyển mã Java7 sang Java8 và tôi đã đưa ra một vấn đề sau. Trong codebase của tôi, tôi có hai phương pháp:Gọi Java 8 đến phương pháp chung là mơ hồ

public static <T> ImmutableSet<T> append(Set<T> set, T elem) { 
    return ImmutableSet.<T>builder().addAll(set).add(elem).build(); 
} 

public static <T> ImmutableSet<T> append(Set<T> set, Set<T> elemSet) { 
    ImmutableSet.Builder<T> newSet = ImmutableSet.builder(); 
    return newSet.addAll(set).addAll(elemSet).build(); 

Compiler trả về lỗi về trận đấu mơ hồ đối với phương pháp thêm trong thử nghiệm sau đây:

@Test(expected = NullPointerException.class) 
public void shouldAppendThrowNullPointerForNullSecondSet() { 
    ImmutableSet<Integer> obj = null; 
    CollectionUtils.append(ImmutableSet.of(1), obj); 
} 

biên dịch báo lỗi:

reference to append is ambiguous both method append(java.util.Set,T) in CollectionUtils and method append(java.util.Set,java.util.Set) in CollectionUtils match

Làm thế nào để viết lại các hàm này để làm việc với suy luận kiểu từ được giới thiệu với Java8?

+1

Bạn có thể làm cho nó hoạt động bằng cách có 'ImmutableSet obj = null; \t \t ImmutableSet set = ImmutableSet.of (1); \t nối thêm (set, obj); '. – Tunaki

+0

Không thể sao chép trong ideone (bằng cách sử dụng HashSet thay vì ImmutableSet, nhưng điều đó không quan trọng từ phối cảnh suy luận kiểu) http://ideone.com/oT6SbF. –

+0

@AndyTurner Không biên dịch được với jdk 1.8.0_51 (và Eclipse Mars.2). – Tunaki

Trả lời

7

Bạn đã tìm thấy các cải tiến Suy luận kiểu mục tiêu tổng quát mới trong Java 8. Có một vài câu hỏi tràn ngăn xếp trên đó. Such as this one.

Java 8 có thể suy ra kiểu trả về của một generic dựa trên phương thức mà nó được chuyển đến làm đối số. Vì vậy, khi bạn gọi CollectionUtils.append(ImmutableSet.of(1), obj), Java 8 đang cố trả lại một tập hợp không thể thay đổi từ cuộc gọi tĩnh of khớp với một trong các phương thức append của bạn. Trong trường hợp này, nó có thể suy nghĩ về việc trả lại một ImmutableSet<Object> thay vì ImmutableSet<Integer> mà bạn đang cố gắng quay trở lại. Và sau đó, không rõ bạn đang gọi số append(Set<Object>, Object) hay append(Set<Integer>, Set<Integer>).

Giải pháp đơn giản nhất là đổi tên phương thức thứ hai appendAll. Hoặc, bạn có thể làm theo các gợi ý sửa chữa here và thay đổi cuộc gọi của bạn đến một cái gì đó như:

CollectionUtils.append(ImmutableSet.<ImmutableSet<Integer>>of(1), obj); 

Tôi muốn gắn bó với đổi tên Phương pháp thứ hai mình mặc dù. Nó sẽ giúp các nhà phát triển khác cùng đau buồn khi họ cố gắng sử dụng thư viện.

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