当使用lambda表达式时,Java实际上会创建一个匿名(非静态)类。非静态内部类总是包含其封闭对象的引用。
当从另一个库中调用此lambda表达式时,该表达式可能在另一个进程中调用lambda,调用因类未找到异常而崩溃,因为它无法在另一个进程中找到封闭对象的类。
考虑这个例子:
public class MyClass {
public void doSomething() {
remoteLambdaExecutor.executeLambda(value -> value.equals("test"));
}
}
Java将创建一个实现某些功能接口的匿名内部类,并将其作为参数传递给executeLambda()。然后remoteLambdaExecutor将整个进程中的匿名类进行远程运行。 远程进程对MyClass一无所知,将抛出
java.lang.ClassNotFoundException: MyClass
因为它需要MyClass用于该封闭对象引用。
我总是可以使用API所期望的功能接口的静态实现,但这会破坏目的并且不会使用lambda功能。
有没有办法用lambda表达式来解决它?
更新:我不能使用静态类,除非它以某种方式导出到其他进程。
答案 0 :(得分:6)
你最初的前提是错误的。 JRE将不生成匿名内部类。它可能会生成一个类,但如果您的lambda表达式不访问该类的this
或非static
成员,则它 将保持对{{ 1}}实例。
但是,这并不意味着课程本身是不必要的。由于该类承载lambda表达式的代码,因此始终需要它。在这方面,使用this
嵌套类的解决方案不会改变它的任何内容,因为它是执行代码所需的static
嵌套类。
如果没有传输包含要执行的代码的类,则无法将对象传输到远程执行工具(除非该类已存在于远程站点)。