Skip to content

Variables inside a lambda block

☕ Java 17 · How Lambdas See the Variables Around Them · 2/4

With curly braces, a lambda body becomes a normal Java block: it can declare variables, use if statements and loops.

A block with local variables

BiFunction<Integer, Integer, Integer> totalEpisodes = (seasons, perSeason) -> {
    int bonus = 1;
    int count = seasons * perSeason;
    return count + bonus;
};

System.out.println(totalEpisodes.apply(3, 8));   // 25
  • bonus and count exist only while the lambda runs. Code outside the braces can't see them.
  • A block that produces a value needs return, and a ; after each statement.
  • The assignment itself still ends with };: forgetting that last semicolon is a classic mistake.

Lambdas share the method's scope

A lambda doesn't get a fresh world for names: it lives inside the scope of the method around it. This version has three mistakes:

void binge(int season) {
    int count = 0;
    Predicate<Integer> p = season -> {   // ❌ season is already a parameter
        int count = 5;                   // ❌ count already exists
        return season > count; }         // ❌ no ; after the closing brace
}

The fix uses fresh names and closes the statement:

void binge(int season) {
    int count = 0;
    Predicate<Integer> p = ep -> {
        int limit = 5;
        return ep > limit; };
}
Rule Why
No reusing a parameter name season is still in scope when the lambda is declared
No redeclaring a local count is already declared in the method
End the statement with }; the ; inside belongs to return, not to the assignment

The same rule applies to the lambda's own parameter: inside m -> { int m = 0; … }, m is already defined.

These clashes are rare in real code, but they appear as soon as lambdas grow long: one more reason to keep them short.

The last place is the trickiest: variables the lambda borrows from outside.

💻 Code: Java17_Part_8_Functional_Programming on GitHub

← Declaring parameters · Next: the effectively final rule →