Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way for Java lambda expression not to have reference to enclosing object?

Tags:

java

lambda

When lambda expression is used Java actually creates an anonymous (non-static) class. Non-static inner classes always contain references their enclosing objects.

When this lambda expression is called from another library that may invoke lambda in a different process that invocation crashes with class not found exception because it cannot find enclosing object's class in another process.

Consider this example:

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

Java will create an anonymous inner class that implements certain functional interface and pass it as a parameter to executeLambda(). Then remoteLambdaExecutor will take that anonymous class across the process to run remotely. Remote process knows nothing about MyClass and will throw

java.lang.ClassNotFoundException: MyClass

Because it needs MyClass for that enclosing object reference.

I can always use a static implementation of the functional interface expected by an API, but that defeats the purpose and doesn't utilize lambda functionality.

Is there way to solve it using lambda expressions?

UPDATE: I cannot use static class either unless it's somehow exported to that other process.

like image 426
ATrubka Avatar asked Feb 25 '16 19:02

ATrubka


People also ask

Can we have exception inside a lambda expression?

A lambda expression body can't throw any exceptions that haven't specified in a functional interface. If the lambda expression can throw an exception then the "throws" clause of a functional interface must declare the same exception or one of its subtype.

Can we use lambda expression without interface?

You do not have to create a functional interface in order to create lambda function.

Can we replace lambda expression with method reference?

The method references can only be used to replace a single method of the lambda expression.

Will lambda expression creates an object whenever it's executed?

Short answer: no. For stateless lambdas (those that do not capture anything from their lexical context), only one instance will ever be created (lazily), and cached at the capture site.


1 Answers

Your initial premise is wrong. The JRE will not generate an anonymous inner class. It may generate a class, but if your lambda expression does not access this or a non-static member of the class, it will not keep a reference to the this instance.

However, this does not imply that the class itself is unnecessary. Since the class hosts the code of the lambda expression, it will always be needed. In this regard, your solution of using a static nested class doesn’t change anything about it, as then, it’s the static nested class that is needed for the execution of the code.

There is no way to transfer an object to a remote execution facility without transferring the class that contains the code to execute (unless the class already exists at the remote site).

like image 53
Holger Avatar answered Sep 28 '22 09:09

Holger