在我的代码中,我有这样的代码:

    private static final List<String> a = new ArrayList<String>() {{
        addAll(b);
        addAll(c);
        add(d);
        add(e);
    }};

我在一些地方读到,双花括号语法创建了一个匿名类或其他东西,这是一个非常糟糕的语法.

由于这是一个静态的最终变量,因此需要在单个逻辑行中设置它.

我发现了使用流在一行中连接列表的代码示例,但没有一个允许添加单个元素.

我正在寻找一种与Java 8兼容的语法,但(如果不同)只与Java的更高版本兼容的更好的语法也会受到欢迎.

推荐答案

不要求在"单个逻辑行"中对static final变量进行初始化.

你可以简单地写

private static final List<String> a = new ArrayList<>();
static {
    a.addAll(b);
    a.addAll(c);
    a.add(d);
    a.add(e);
}

它被称为静态初始化器块.


请注意,由于该列表在整个运行时期间将保持可变,因此您可以在任何时间、任何地点向该列表添加内容.

因为您可能不需要这样,而是使用类初始化了一个真正不变的列表,所以您甚至可以编写

private static final List<String> a;
static {
    List<String> tmp = new ArrayList<>();
    tmp.addAll(b);
    tmp.addAll(c);
    tmp.add(d);
    tmp.add(e);
    a = List.copyOf(tmp);
}

换句话说,将初始值设定项块末尾的字段与最终结果一起赋值.

List.copyOf(…)(从Java 9开始)创建了一个不可变的副本,但不允许null个元素,一般来说,null的值是very strict behavior.

如果您需要一个支持空的不可修改的列表,您可以使用tmp.stream().toList()(从Java版本16开始).


但是,即使对于那些不了解静态初始化器的人来说,对于复杂的字段初始化器,也有一个非常简单的解决方案:

private static final List<String> a = createA();

private static List<String> createA() {
    List<String> tmp = new ArrayList<>();
    tmp.addAll(b);
    tmp.addAll(c);
    tmp.add(d);
    tmp.add(e);
    return List.copyOf(tmp);
}

Java相关问答推荐

是否需要关闭Executors返回的执行器.newVirtualThreadPerTaskExecutor()?

Java Streams在矩阵遍历中的性能影响

在现代操作系统/硬件上按块访问数据值得吗?

尽管类型擦除,instanceof与泛型在Java中如何工作?

CAMEL 4中的SAXParseException

S的字符串表示是双重精确的吗?

存根基类的受保护方法

Java 21 struct 化连接货币,需要可预知的子任务异常排序

Spring和可编辑";where";@Query

内存和硬盘中的Zip不同,这会导致下载后的Zip损坏

buildDir:File!&#的getter解决方案是什么?39.被抛弃

根本不显示JavaFX阿拉伯字母

从LineChart<;字符串、字符串和gt;中删除数据时出现特殊的ClassCastException;

Java在操作多个属性和锁定锁对象时使用同步和易失性

JavaFX标签中的奇怪字符

使IntelliJ在导入时优先 Select 一个类或将另一个标记为错误

JPA无手术同品种器械可能吗?

Java List有一个在一个位置添加多个元素的方法,但我找不到一个在一个位置删除多个元素的方法

让标签占用JavaFX中HBox的所有可用空间

人们在 IntelliJ 上将-Dhttp.proxyHost=your.proxy.net -Dhttp.proxyPort=8080放在哪里?