有没有办法改变Java Lambda捕获的值

时间:2018-05-04 02:01:12

标签: java lambda

类似的东西:

    Integer value = 3;
    Consumer<Integer> consumer = input -> {
        value = value * 2;
    };
    consumer.accept(100);
    System.out.println(value);

谢谢! [解决]

    AtomicInteger value = new AtomicInteger(3);
    Consumer<Integer> consumer = input -> {
        value.getAndAdd(5); // 8
        System.out.println(value.get());
    };
    consumer.accept(100);
    System.out.println(value.get()); // 8

也感谢Umer Farooq的回答 Modifying local variable from inside lambda

2 个答案:

答案 0 :(得分:3)

不,那是不可能的。

JLS 15.27.2说:

  

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

由于你在lambda中使用value,但是在lambda之外声明它,它必须是final或者有效的final。这意味着你不能多次为它赋值。

当然,如果value是一个可变对象(例如AtomicInteger),那么能够改变它。 <{1}}引用本身将保持不变,但它引用的对象将被更改。

答案 1 :(得分:0)

因为Java编译器只允许在lambda或匿名内部类中访问final或成员引用,所以答案是否定的。但是,您可以(正如您似乎找到的那样)更改最终参考中的状态。

您找到了AtomicInteger的解决方法,在您修改Integer时,该解决方法适用于您的具体情况。将引用放在最终的单值数组中将适用于所有内容。它不是很漂亮,但如果您使用IntelliJ,如果您尝试在这种情况下修改最终状态,它将为您提供此更改。

以下是一个例子:

final int[] value = { 3 };
Consumer<Integer> consumer = input -> {
    value[0] = value[0] * 2;
};
consumer.accept(100);
System.out.println(value[0]);