java - 使用包括 block 初始值设定项的匿名类初始化静态 ArrayList 字段

标签 java arraylist initialization

我在玩 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 也通过包含 block 初始化程序的匿名类进行初始化。 但问题是我们将“John”添加到“this”引用并打印 NAMES,因此它显示为 null。 如果我们以这种方式进行更改,代码将正确运行:

System.out.println(this);

代替:

System.out.println(NAMES);

为什么会这样?

最佳答案

当你使用“双括号”初始化时,你正在创建一个带有外括号的 ArrayList 的匿名子类,内括号代表实例初始化器,你在其中调用 添加并打印出NAMES。但是在构造ArrayList的时候,ArrayList还没有构造完成,还没有赋值给NAMES 还。变量 NAMES 仍具有默认值 null

虽然语法看起来很漂亮,但通常不值得为了简单的初始化而创建一个匿名子类。

相反,如果这必须静态完成,则将列表内容的初始化移动到静态初始化程序 block ,以便 NAMES 在被引用时已经初始化。

private static final List<String> NAMES = new ArrayList<String>();
static {
    NAMES.add("John");
    System.out.println(NAMES);
}

关于java - 使用包括 block 初始值设定项的匿名类初始化静态 ArrayList 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51090903/

相关文章:

java - "Throwable"应该被抛出吗?

java - 将 ArrayList<HashMap<String, String>> 追加到另一个 ArrayList<HashMap<String, String>>

c++ - 初始化作为另一个结构成员的结构 - ISO C++

C++零初始化 - 为什么这个程序中的 `b`未初始化,但 `a`已初始化?

java - 编写一个从 arraylist 返回迭代器的方法

java - 时间复杂度说明

Java ArrayList.clear() 函数

java - java中的集合(如何单独打印对象)

c - C中调用模块初始化代码的自动编译时机制

java - SWT Canvas 是否提供鼠标移动/单击 Activity 区域的工具?