2

I was just trying out few java-8 functional programming , I had few doubts on the behaviour of the lamda expressions. I have tried to explain the problem below with simple Command Pattern.

public interface Editor {
    public void open();
    public void close();
//  public void save();

}

Editor Implementation

public class MyEditor implements Editor {

    @Override
    public void open() {
        System.out.println("...opening");

    }

    @Override
    public void close() {
        System.out.println("...closing");
    }

}

Interface Action

// this is actually a @FunctionalInterface
public interface Action {
    public void perform();

}

Actionable items.

public class Open implements Action {

    private final Editor editor;

    public Open(Editor editor) {
        this.editor = editor;
    }

    @Override
    public void perform() {
        editor.open();
    }

// Similarly Close implements Action...

...

A Macro to run all the actions.

public class Macro {

    private final List<Action> actions;

    public Macro() {
        actions = new ArrayList<>();
    }

    public void record(Action action) {
        actions.add(action);
    }

    public void run() {
        actions.forEach(Action::perform);
    }
}

Now running the Macro is where the interesing part is .

public class RunMacro {
    public static void main(String[] args) {
        Editor editor= new MyEditor();
        Macro macro = new Macro();
        macro.record(() -> editor.open());// Line 4
        macro.record(new Close(editor));  // Line 5
        macro.run();
    }
}

My question is , during the execution of Line 4, How does Java understand that to create a instanceof Open and add it into macro. In short lamdba expressions is behaving same way as Line 5. This whole pattern becomes a lot simpler with lambda expressions BUT does the functional programming with OOPS makes the development at very abstract level or less verbose?

Courtesy of problem : O'Reilly Media : Java 8 Lamdbas

Could any one please clarify this.?

2 Answers 2

7

How does Java understand that to create a instanceof Open and add it into macro ?

You should read the section Target Typing in Lambda Expressions of the java tutorial. When you wrote:

macro.record(() -> editor.open());

Your are not creating an instance of the Open class. You are not creating an instance of a generated anonymous class.

See Translation strategy section in Translation of Lambda Expressions.

Instead of generating bytecode to create the object that implements the lambda expression (such as calling a constructor for an inner class), we describe a recipe for constructing the lambda, and delegate the actual construction to the language runtime. That recipe is encoded in the static and dynamic argument lists of an invokedynamic instruction.


You could also take advantages of the java 8 method references, and simplify again the code:

    Editor editor= new MyEditor();
    Macro macro = new Macro();
    macro.record(editor::open);
    macro.record(editor::close);
    macro.run();

at last you may remove the Action interface and use the Runnable one. This allow for example to use all the stuff of the java.util.concurrent like Executor, the new java promise: CompletableFuture...

Sign up to request clarification or add additional context in comments.

3 Comments

Right, i really like method references. And java 8 introduces a lot of great stuff without losing its simplicity. The greater java release
I second you, I can say this blend makes Java more programmable and of course always developer friendly.
Full Disclosure: I'm the author of Java 8 Lambdas. I've upvoted this answer rather than adding my own because I think its a pretty good answer! If you want to understand Target Typing in more detail then it might be worth reading over the section called "Type Inference" which starts on page 11.
0

Lambda constructs are a very readable replacement for a construct that is a long-time part of the Java language: anonymous classes. In fact, regarding the intention you can think of a lambda expression as an anonymous class, although technically there is a big difference.

Just to add a third variant for your record method:

macro.record(new Action() {
    @Override public void perform() { editor.open(); }
});

Here you are passing an instance of an anonymous class (a subclass of Action) to the recording method. This is the same with the lambda expression:

macro.record(() -> editor.open());

For these two variants you even do not need the Open class. Try it out and remove it from the sources.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.