java - 使用包括块初始化程序的匿名类初始化静态 ArrayList 字段
问题描述
我在玩 javaDeathmatch 游戏,遇到了一个我无法回答的问题。你能帮助我吗?
public class DeathMatch {
private static final List<String> NAMES = new ArrayList<>() {{
add("John");
System.out.println(NAMES);
}};
public static void main(String[] args) {
//Nothing in particular
}
}
在这种情况下,当我们运行 JVM 时,将加载该类,首先创建并初始化其静态成员“NAMES”。ArrayList 也通过包括块初始化程序的匿名类进行初始化。但问题是我们将“John”添加到“this”引用并打印 NAMES,因此它显示为 null。如果我们以这种方式进行更改,代码将正确运行:
System.out.println(this);
代替:
System.out.println(NAMES);
为什么会这样?
解决方案
当您使用“双大括号”初始化时,您将创建一个ArrayList
带有外大括号的匿名子类,而内大括号对代表实例初始化程序,您将在其中调用add
并打印NAMES
. 但是在您构建 时ArrayList
,ArrayList
尚未完成构建,并且尚未分配给它NAMES
。该变量NAMES
仍然具有其默认值null
。
虽然语法可能看起来很漂亮,但通常不值得仅仅为了便于初始化而创建匿名子类。
相反,如果这必须静态完成,则将列表内容的初始化移动到静态初始化程序块,以便NAMES
在引用时已经初始化。
private static final List<String> NAMES = new ArrayList<String>();
static {
NAMES.add("John");
System.out.println(NAMES);
}
推荐阅读
- ionic4 - ionic 4 从 Json 创建动态多步表单
- android - 颤振中的闪屏出现在哪里?
- python - 创建一个遍历数据帧行的函数,应用 scipy 函数,将输出附加到新列并输出修改后的数据帧
- angular - 将变量动态更改为 ngmodel 不起作用
- python - 我试图在 python 上解决以下问题,我得到了正确的输出,但它们仍然显示错误
- google-apps-script - 在 1 个主 onEdit 下运行的 onEdit 脚本太多?GoogleSheets / Google Apps 脚本
- c++ - 有没有办法在使用矢量浮点数时避免来自 clang++(紫红色默认参数)的警告?
- python - 如何复选框以启用 Tkinter 中的按钮
- ios - 使用指针从 Parse 中保留行
- matrix - R中的商在矩阵中保持位置