如何在不将变量重新分配给最终变量的情况下使用lambda?

时间:2016-02-17 18:07:29

标签: java lambda

我总是要将我的变量重新分配给另一个标记为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);
    });
}

如果有另一种方式声明我的变量在open调用之前不会被更改,那将会非常棒。

3 个答案:

答案 0 :(得分:5)

你做不到。这在JLS section 15.27.2中明确指定:

  

使用但未在lambda表达式中声明的任何局部变量,形式参数或异常参数必须声明为final或者是有效的final(§4.12.4),否则在尝试使用时会发生编译时错误。

但是,您可以将示例重写为以下内容:

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

我们只是声明一个将被重复使用的final变量newvar

答案 1 :(得分:2)

lambda只能从final或“有效最终”的封闭上下文中访问变量和方法参数。后者指的是在其范围内从未修改过的变量和参数。重要的是要理解标准在使用lambda之前不是“未更改”,而是在首次设置值后从不更改。

答案 2 :(得分:0)

如果你不特别喜欢制作另一个变量,那么如何使用辅助方法创建/返回你要传递给open(...)的lambda,如下所示:

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

然后你可以像这样使用它:

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

如果我的类型错误,您可以使用适当的方式更改功能接口。您也可以使用方法引用将doOtherThing方法传递到helper(...)