2013-03-01 29 views
6

Tôi đang thử nghiệm các tính năng đóng mới của Java 8; Tôi đang tự hỏi tại sao đoạn mã nàyĐóng cửa Java 8 và nhận dạng loại

public class Test8 { 
    private class A { int a;} 
    private class B { int b;}  
    interface IFA { void ifa(A param); } 
    interface IFB { void ifb(B param); } 
    private void forceA(A expr) { }  
    private void z(IFA fun) { System.out.println("A"); fun.ifa(new A()); } 
    private void z(IFB fun) { System.out.println("B"); fun.ifb(new B()); }  

    public void run() { 
     z(x -> forceA(x)); 
    } 
    public static void main(String args[]) { new Test8().run(); } 
} 

cung cấp cho các lỗi: both method z(IFA) in Test8 and method z(IFB) in Test8 match error trên gọi z trong phương pháp chạy

Không phải là trình biên dịch có thể phát hiện rằng forceA gọi lực lượng x là các loại A và do đó z chính xác để sử dụng là z(IFA fun)?

(một chức năng tương tự là hợp pháp trong C# sử dụng đại biểu; là có một cách để có được kết quả tương tự trong Java 8?)

+2

Nếu điều này không biên dịch, thì trình biên dịch rõ ràng không đủ thông minh để tìm ra điều đó. –

Trả lời

3

Java 8 vẫn đang trong quá trình thực hiện. Thông số mới nhất cho phép mã của bạn hoạt động. Việc triển khai trình biên dịch sẽ sớm bắt kịp.

Tuy nhiên, loại quá tải này không phải là một phong cách tốt. Chúng tôi có chữ ký

z(A->void) 
    z(B->void) 

sau đó khi javac thấy

z(arg->{ block }) 

nó không rõ ràng mà z() áp dụng. Công việc phụ phải được thực hiện (bằng cách biên dịch khối) để chọn một.

Chúng tôi không thực sự quan tâm về mức độ khó khăn của javac. Vấn đề thực sự là, khi một con người nhìn thấy mã đó, con người phải đào sâu hơn để hiểu được cái nào được gọi là z(). Không phải là rất dễ đọc.

Theo quy tắc chung, tránh quá tải phương thức với giao diện chức năng của cùng một tính chất. arities khác nhau cũng tốt, không có vấn đề để disambiguate, cho con người hoặc javac

z(arg->{...}) 

    z((arg1,arg2)->{...}) 

Một hình thức quá tải cũng được ban phước bởi các nhà thiết kế (Dan Smith vv) - cùng arity, các loại tham số giống nhau, nhưng kiểu trả về khác nhau

z(X->R1) 
    z(X->R2) 

nhưng tôi nghĩ nó khá khó hiểu và tôi sẽ tránh nó.

+0

Cảm ơn, tôi sẽ thử phiên bản mới của trình biên dịch ngay khi được xuất bản. Tôi biết rằng nó không phải là một phong cách tốt, nhưng tôi chỉ kiểm tra khả năng ngôn ngữ (đóng cửa). – Vor

0

Cơ thể của lambda không được sử dụng để xác định loại của nó. Giống như phương pháp. Tôi đoán một tham chiếu phương pháp có thể làm việc. Nhưng euw, quá tải.