2
    int x = 1;
    Consumer<Object> f = (i) -> {
        int x = 1; // invalid
    };

vs.

    Consumer<Object> f = (i) -> {
        int x = 1;
    };
    int x = 1; // valid

Imagine those two blocks inside a method. Why is the second block valid?

2 Answers 2

5

This is very similar to normal Java scopes:

int i;
{
    int i;      // invalid
}          

vs.

{
    int i;      // valid
}

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

1 Comment

I was going to write the exact same thing!
4

In the first block you are "shadowing" the original x variable. You will not be able to access the first x anymore by creating a new x.

The second block is okay, because the second x is created on a moment when the first x does not longer exists (it is out of scope).

Basically: in the first case, you are trying to have two variables called x at the same time. In the second case, you are creating two x variables after each other: their lifetimes will not overlap.

8 Comments

why isnt the "scope" symmetric then. IF lambdas are so transparent then it should be symmetric
But scope simply isn't symmetric. Not even for constructs like for loops or if statements.
lol, so lambdas (as if-blocks etc.) dont create a naming scope, but create a lifetime scope? why?
It would, of course, be a perfectly legal design to allow redeclaring (as in "shadowing") variables in inner scopes. Again, it's just language design. But it introduces a level of confusion (dealing with variables of the same name with different values depending on the scope) that has no actual benefit (just using a different name is easy enough).
+1. This has nothing to do with lambdas; e.g. anonymous classes would impose the same constraints.
|

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.