1

I always have to reassign my variable to another variable marked as final:

public void method(int myvar) {

    myvar = myvar + 1;

    doSomething(myvar); //I need to change myvar before the lambda

    final int newvar = myvar; //this line is stupid
    //could be something like:
    //makefinal myvar;

    open(con -> {
        doOtherThing(newVar);
    });
}

Would be really great if there was another way to declare that my variable will not be changed before the open call.

5
  • lets say I NEED to do myvar + 1 before open Commented Feb 17, 2016 at 18:23
  • In that case you should use an additional variable anyways, for the same reason as above. And lambdas explicitly only work with final variables. Commented Feb 17, 2016 at 18:24
  • Would be nice if I could mark myvar in a way specifically to tell it will be final before open, instead of assigning to another variable Commented Feb 17, 2016 at 18:27
  • That's not possible. A variable can't be made final subsequently. Commented Feb 17, 2016 at 18:29
  • alright. I think the main problem is the need of the final variable, in C# this is not needed Commented Feb 17, 2016 at 18:55

3 Answers 3

5

You can't. This is explicitely specified in the JLS section 15.27.2:

Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.

However, you can rewrite your example to the following:

public void method(int myvar) {
    final int newvar = myvar + 1;
    doSomething(newvar);
    open(con -> doOtherThing(newvar));
}

We're simply declaring a final variable newvar that will be reused.

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

1 Comment

@melanke See my edit. I still don't see the problem.
2

A lambda may only access variables and method parameters from the enclosing context that are final or "effectively final". The latter refers to variables and parameters that are never modified within their scope. It is important to understand here that the standard is not "unchanged before the lambda is used", but rather never changed after its value is first set.

Comments

0

if you don't particularly like making another variable, how about using a helper method to create/return the lambda you want to pass into open(...), like so:

public static < T > Consumer< T > helper( IntFunction< T > func, int var ) {
    return con -> func.apply( var );
}

and then you can use it like so:

public void method( int myvar ) {
    myvar = myvar + 1;
    doSomething( myvar ); //I need to change myvar before the lambda
    open( helper( arg -> doOtherThing( arg ), myvar ) );
}

If I got the types wrong, you can change the functional interfaces with whatever is appropriate. Also you can probably use a method reference to pass the doOtherThing method into helper(...).

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.