2014-09-03 29 views
15

Tôi có hai chức năng tương tự như những người thân:Java 8 giao diện chức năng tham khảo mơ hồ (đây là một lỗi?)

public static <In extends Number, Out extends Number> Out test(In in, Function<In, Out> f) { 
    Out x = f.apply(in); 
    return test(in, x); 
} 

public static <In extends Number, Out extends Number> Out test(In in, Out out) { 
    return out; 
} 

Đối với tôi nó là rõ ràng rằng họ không thể đụng độ và các cuộc gọi có thể không được mơ hồ (!) . Tuy nhiên, với phiên bản mới nhất của Java 8, cuộc gọi sau thất bại:

Test.test(2, Integer::new); 

với Error:(17, 16) java: reference to test is ambiguous both method <In,Out>test(In,java.util.function.Function<In,Out>) in org.test and method <In,Out>test(In,Out) in org.test match

khi

Test.test(2, new Function<Integer, Number>() { 
    @Override 
    public Number apply(Integer integer) { 
     return 10; 
    } 
}); 

Test.test(2, (Function<Integer, Number>) integer -> 10); 

làm việc.

Đây có phải là một lỗi trong trình biên dịch (hoặc này nên thất bại?)

biết thêm thông tin về thiết lập của tôi dưới đây

phiên bản

Java:

Desktop $ java -version 
java version "1.8.0_05" 
Java(TM) SE Runtime Environment (build 1.8.0_05-b13) 
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode) 

Lỗi:

Test.java:5: error: reference to test is ambiguous 
    Test.test(2, Integer::new); 
     ^
both method <In#1,Out#1>test(In#1,Function<In#1,Out#1>) in Test and method <In#2,Out#2>test(In#2,Out#2) in Test match 
where In#1,Out#1,In#2,Out#2 are type-variables: 
In#1 extends Number declared in method <In#1,Out#1>test(In#1,Function<In#1,Out#1>) 
Out#1 extends Number declared in method <In#1,Out#1>test(In#1,Function<In#1,Out#1>) 
In#2 extends Number declared in method <In#2,Out#2>test(In#2,Out#2) 
Out#2 extends Number declared in method <In#2,Out#2>test(In#2,Out#2) 

Chương trình thử nghiệm:

import java.util.function.Function; 

public class Test { 
    public static void main(String[] args) { 
    Test.test(2, Integer::new); 
    } 

    public static <In extends Number, Out extends Number> Out test(In in, Function<In, Out> f) { 
    Out x = f.apply(in); 
    return test(in, x); 
    } 

    public static <In extends Number, Out extends Number> Out test(In in, Out out) { 
    return out; 
    } 
} 

Vì vấn đề được xác nhận bởi người khác, tôi đã báo cáo đó là lỗi cho Oracle.

+0

'Test.test (2, (Hàm ) Integer :: new)' làm việc cho tôi. Cách của bạn không cho tôi quá ('java -version' mang lại cho tôi' 1.8.0'). – ajb

+0

Làm việc trong Eclipse. –

Trả lời

4

Test.test(2, Integer::new); không nên thất bại. Thật vậy, nó không không thất bại đối với tôi. Đang chạy:

C:\Users\David>java -version 
java version "1.8.0_20" 
Java(TM) SE Runtime Environment (build 1.8.0_20-b26) 
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode) 
C:\Users\David>javac -version 
javac 1.8.0_20 

Từ những gì tôi có thể nói, đây là lần gần đây nhất. Bạn đang làm việc trên nền tảng nào?

Hóa ra, đây là lỗi trên OSX (chứ không phải trên Windows). Nếu ai đó có hộp * NIX, họ cũng nên kiểm tra mã OP.

+0

Cảm ơn! Có vẻ như tôi đã cài đặt 'javac 1.8.0_05' trên OSX. (cập nhật câu hỏi của tôi với nhiều thông tin hơn) – isakkarlsson

+0

@isakkarlsson: chắc chắn đã là một lỗi rồi. Rất may, phiên bản mới nhất của javac (1.8.0_20) sửa chữa nó. –

+1

Có lẽ trên cửa sổ. Tôi vừa cập nhật thành 'javac -version':' javac 1.8.0_20'. Lỗi vẫn tồn tại. – isakkarlsson

1

Tôi có cùng một vấn đề, nhưng tôi đã cố gắng này:

Test.test(2, Function.identity()); // OK 
Test.test(2, val -> 2L); // FAIL 
Test.test(2, Function.<Integer>identity().andThen(a -> a * 2)); // OK 
Test.<Integer,Long>test(2, val -> 2L); // OK 
Test.test(2, (final Integer a) -> a* 2); // FAIL 

Trong khi điều này bị lỗi trong Javac (Debian Wheezy + jdk1.8.0_20x64), nó hoạt động tốt trong Eclipse.

Một lưu ý phụ, tôi đoán đó là một trong những vấn đề về suy luận kiểu. Bạn có lẽ nên điền vào một báo cáo lỗi.

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