我总是要将我的变量重新分配给另一个标记为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
调用之前不会被更改,那将会非常棒。
答案 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(...)
。