2016-02-25 26 views
9

Khi biểu thức lambda được sử dụng Java thực sự tạo ra một lớp ẩn danh (không tĩnh). Các lớp bên trong không tĩnh luôn chứa các tham chiếu các đối tượng kèm theo của chúng. Khi biểu thức lambda này được gọi từ một thư viện khác có thể gọi lambda trong một tiến trình khác mà gọi sự cố với lớp không tìm thấy ngoại lệ vì nó không thể tìm thấy lớp của đối tượng kèm theo trong một tiến trình khác.Có cách nào để biểu thức Java lambda không có tham chiếu đến đối tượng kèm theo không?

Hãy xem xét ví dụ sau:

public class MyClass { 
    public void doSomething() { 
     remoteLambdaExecutor.executeLambda(value -> value.equals("test")); 
    } 
} 

Java sẽ tạo ra một lớp bên trong vô danh mà thực hiện giao diện chức năng nhất định và vượt qua nó như một tham số để executeLambda(). Sau đó remoteLambdaExecutor sẽ lấy lớp ẩn danh đó trong quá trình chạy từ xa. Quá trình từ xa không biết gì về MyClass và sẽ ném

java.lang.ClassNotFoundException: MyClass 

Vì nó cần MyClass cho tham chiếu kèm theo đó.

Tôi luôn có thể sử dụng triển khai tĩnh giao diện chức năng được mong đợi bởi API, nhưng điều đó đánh bại mục đích và không sử dụng chức năng lambda.

Có cách nào để giải quyết nó bằng cách sử dụng biểu thức lambda không?

CẬP NHẬT: Tôi không thể sử dụng lớp tĩnh trừ khi bằng cách nào đó được xuất sang quy trình khác.

+0

'có thể gọi lambda trong một tiến trình khác': âm thanh giống như chihuahua – wero

+0

Có lẽ Java là ngôn ngữ sai cho việc này. Có lẽ bạn cần một ngôn ngữ kịch bản. –

Trả lời

6

Tiền đề ban đầu của bạn là sai. JRE sẽ không phải tạo lớp bên trong ẩn danh. Nó có thể tạo ra một lớp, nhưng nếu biểu thức lambda của bạn không truy cập this hoặc thành viên không phải là static của lớp, nó sẽ không giữ tham chiếu đến cá thể this.

Tuy nhiên, điều này không ngụ ý rằng chính lớp đó là không cần thiết. Vì lớp này lưu trữ mã của biểu thức lambda, nên sẽ luôn cần thiết. Về vấn đề này, giải pháp của bạn về việc sử dụng lớp học lồng nhau static không thay đổi bất kỳ điều gì về nó, khi đó, đó là lớp học được lồng vào là static cần thiết để thực thi mã.

Không có cách nào để chuyển đối tượng đến cơ sở thực thi từ xa mà không chuyển lớp chứa mã để thực thi (trừ khi lớp đã tồn tại ở trang từ xa).

+1

Nói cách khác, một lambda Java giống như một con trỏ hàm C++ hơn là một Lisda lambda. Java lambda cho bạn biết mã nào để chạy, nhưng không thực sự chứa mã đó. Tôi đã không nhận ra điều này. –

+0

Nếu không, truy cập vào các biến của phạm vi xung quanh cũng sẽ không thể, xem https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#accessing-local-variables –

+0

Holger, bạn đã đúng . Giả định của tôi sai. Câu hỏi vẫn đứng vững. Có cách nào để làm điều đó? Có lẽ có? – ATrubka

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