gpt4 book ai didi

Lambda 在初始化之前访问封闭类的最终字段

转载 作者:行者123 更新时间:2023-12-02 09:28:59 24 4
gpt4 key购买 nike

当从封闭的 lambda 表达式访问类的 Final 字段时,我发现了无法解释的行为。这是示例程序:

public class FinalAccessTest {

// Some fields
private int nonfinalfield=4;
private final int directfinalfield=5;
private final int constructorfinalfield;

// element method for the final field with delayed assignment
private int getConstructorFinalField() { return constructorfinalfield; }

// Some lambda expressions accessing the fields from above
private final Supplier<Integer> nonfinalsupp=()->nonfinalfield; // OK
private final Supplier<Integer> directfinalsupp=()->directfinalfield; // OK
private final Supplier<Integer> constructorfinalsuppA=
()->this.constructorfinalfield; // OK
private final Supplier<Integer> constructorfinalsuppB=
()->getConstructorFinalField(); // OK

// This one does not compile: The blank final field
// constructorfinalfield may not have been initialized
//private Supplier<Integer> constructorfinalsuppC=()->constructorfinalfield;

public FinalAccessTest() {
System.out.println(constructorfinalsuppA.get()); // prints "0"
System.out.println(constructorfinalsuppB.get()); // prints "0"

// Does not compile: "may not have been initialized"
//System.out.println(constructorfinalfield);

constructorfinalfield=6;
System.out.println(constructorfinalsuppA.get()); // prints "6"
System.out.println(constructorfinalsuppB.get()); // prints "6"
System.out.println(constructorfinalfield); // Compiles and prints "6"

// now access to a non-final field
System.out.println(nonfinalsupp.get()); // prints "4"
nonfinalfield=17;
System.out.println(nonfinalsupp.get()); // prints "17"

}

public static void main(String[] args) { new FinalAccessTest(); }

}

显然,可以访问类的最终字段,该字段在 lambda 表达式中实际初始化之前在构造函数中初始化

  • 通过 this.<field> 引用该字段
  • 或使用元素方法 get<Field>() .

另一方面,似乎通常不可能通过简单地引用<field>来访问这样的final字段。在 lambda 表达式中。我想,this在 lambda 中始终引用封闭类,以便 <field>this.<field>实际上是相同的。

为了避免混淆,这一切仅适用于在构造函数中初始化final字段。对于非final字段或者在声明中初始化的final字段,通过<field>访问完全有可能,并且在 lambda 调用时使用该字段的值。

这是怎么回事?这是 lambda 表达式定义/引擎的普遍缺点、特定 Java 版本 (8u66) 中的错误还是只是一个功能?我有点疑惑。我错了什么?

最佳答案

对象初始值设定项(即类中表单字段=值的声明)按出现顺序在构造函数之前运行。因此,第一个声明了当时已经初始化的所有访问字段,而在构造函数中创建的字段只会在相应的对象初始化器之后初始化。

关于Lambda 在初始化之前访问封闭类的最终字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37441842/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com