Lambda 表达式没有有效的 final 变量

Lambda Expression works with no effectively final variable

我读到 lambda 表达式使用的外部变量必须是最终的或实际上是最终的。 例如,如果我尝试修改 Supplier 主体中的外部字符串值,编译器会阻止我,正如上面的定义。 但是如果我使用外部 Pojo(修改它的属性 - 所以它的内部状态),那么它可以正常工作并否定上面的声明。

怎么来的?

package com.quicktutorialz.test;

import java.util.function.Supplier;

public class MainApplication {

  public static void main(String[] args){

    // MY NON-EFFECTIVELY-FINAL POJO
    NamePojo namePojo = new NamePojo();
    namePojo.setName("Luisa");

    //MY LAMBDA
    Supplier<String> supplier = () -> {
        namePojo.setName("Alex");  //HOW IS THAT POSSIBLE?!?!
        return "Hello " + namePojo.getName();
    };

    System.out.println(supplier.get());


  }
}

class NamePojo {
  String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

变量(实际上)是最终的,它的字段不是。

您正在混合最终变量和不可变变量。

final 变量意味着它不能被重新赋值。示例:

void doSomething() {
  int a = 0;  // is effectively final
  int b = 1;  // is not effectively final
  b = 2;
}

不可变变量意味着它的外部表示不会改变。这主要意味着它的字段是 final 或实际上是最终的。示例:

class A {
  int value;
  A(int value) { this.value = value; }
  int getValue() { return this.value; }
}

public void doSomething() {
  A a = new A(0);
  // no way to change a.value
}

你的情况:

public class MainApplication {

  public static void main(String[] args){

    // MY NON-EFFECTIVELY-FINAL POJO
    NamePojo namePojo = new NamePojo();    // namePojo is assigned.
    namePojo.setName("Luisa");             // namePojo is changed, but not reassigned.

    //MY LAMBDA
    Supplier<String> supplier = () -> {
      // namePojo is changed, but not reassigned.
      namePojo.setName("Alex");  //HOW IS THAT POSSIBLE?!?!
      return "Hello " + namePojo.getName();
    };

    System.out.println(supplier.get());

  }
}

变量namePojo内容更改,但变量本身从未重新分配,因为它没有重新分配,所以它实际上是最终的。对 namePojo 的引用在您的代码中从未更改,使其 最终有效