JAVA 双括号初始化

这段代码中的 new ArrayList<Object>() {{ ... }} 是一种特殊的语法,称为 双括号初始化(Double Brace Initialization)。它结合了匿名内部类和实例初始化块的特性,用于快速创建并初始化一个集合对象(如 ArrayList)。下面我们来详细分析为什么这种写法会放在这个位置,以及它的作用。


1. 为什么放在这个位置?

在这段代码中:

List<Map<String, Object>> tableList = queryTool.query(tableQuery, new ArrayList<Object>() {{
    add(datasource.getDatabaseName());
    if (StringUtils.isNotEmpty(oldTableName)) {
        add(oldTableName);
    }
}});
  • queryTool.query 方法的第二个参数

    • 从方法签名来看,queryTool.query 的第二个参数是一个 List<Object> 类型。
    • 这里需要传递一个 ArrayList<Object> 对象作为参数。
  • new ArrayList<Object>() {{ ... }} 的作用

    • 使用双括号初始化的方式,可以快速创建一个 ArrayList 对象,并在创建的同时向其中添加元素。
    • 这种写法避免了先创建一个空的 ArrayList,然后再通过多次调用 add() 方法添加元素的繁琐操作。

因此,这段代码直接在方法调用的位置创建了一个包含所需元素的 ArrayList,并将其作为参数传递给 queryTool.query 方法。


2. 双括号初始化的工作原理

(1) 外层括号:匿名内部类
  • new ArrayList<Object>() { ... } 创建了一个匿名内部类,继承自 ArrayList<Object>
  • 由于没有定义任何新的方法或覆盖现有方法,这个匿名内部类的行为与普通的 ArrayList 完全一致。
(2) 内层括号:实例初始化块
  • 内层的 {{ ... }} 是一个 实例初始化块(Instance Initializer Block)。
  • 实例初始化块会在对象构造时执行,类似于构造函数中的代码。
  • 在这里,add(datasource.getDatabaseName()) 和 add(oldTableName) 是在对象创建时立即执行的操作。
等价代码

如果不使用双括号初始化,这段代码可以改写为以下形式:

 
List<Object> params = new ArrayList<>();
params.add(datasource.getDatabaseName());
if (StringUtils.isNotEmpty(oldTableName)) {
    params.add(oldTableName);
}
List<Map<String, Object>> tableList = queryTool.query(tableQuery, params);

可以看到,双括号初始化是一种更简洁的写法,但它的本质是相同的。


3. 为什么选择双括号初始化?

优点
  1. 简洁性

    • 直接在创建对象的同时完成初始化,减少了代码量。
    • 特别适合在需要传递临时集合对象的场景中使用。
  2. 可读性

    • 对于简单的初始化操作,双括号初始化可以让代码看起来更加紧凑。
缺点
  1. 性能开销

    • 双括号初始化实际上创建了一个匿名内部类,这会导致额外的类加载和内存占用。
    • 对于频繁调用的场景,可能会对性能产生一定影响。
  2. 序列化问题

    • 匿名内部类会持有外部类的引用,如果将这个集合对象用于序列化(如存储到文件或通过网络传输),可能会导致意外的序列化问题。
  3. 维护性

    • 如果初始化逻辑较复杂,双括号初始化可能会降低代码的可读性和可维护性。

4. 替代方案

如果担心双括号初始化的性能问题或潜在风险,可以使用传统的写法,例如:

(1) 显式创建并初始化
 
List<Object> params = new ArrayList<>();
params.add(datasource.getDatabaseName());
if (StringUtils.isNotEmpty(oldTableName)) {
    params.add(oldTableName);
}
List<Map<String, Object>> tableList = queryTool.query(tableQuery, params);
(2) 使用 Java 9+ 的 List.of 或 Stream

如果不需要修改集合内容,可以使用不可变集合(Java 9+ 提供的 List.of 方法):

 
List<Object> params = Stream.of(
        datasource.getDatabaseName(),
        StringUtils.isNotEmpty(oldTableName) ? oldTableName : null
    )
    .filter(Objects::nonNull)
    .collect(Collectors.toList());
List<Map<String, Object>> tableList = queryTool.query(tableQuery, params);

5. 总结

  • 双括号初始化 是一种方便的语法糖,用于快速创建并初始化集合对象。
  • 在这段代码中,new ArrayList<Object>() {{ ... }} 的作用是直接在方法调用的位置创建一个包含所需元素的 ArrayList,并将其作为参数传递给 queryTool.query 方法。
  • 尽管双括号初始化简洁高效,但在性能敏感或需要序列化的场景中,建议使用传统的写法或现代的集合工具(如 List.of 或 Stream)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值