当前位置: 首页 > news >正文

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)。

相关文章:

  • 消防设施操作员考试重点考哪些内容呢?
  • Byte-Buddy系列 - 第2讲 方法拦截与委托实现
  • 1ll C++
  • STM32F407使用ESP8266连接阿里云并上传数据
  • MySQL【8.0.41版】安装详细教程--无需手动配置环境
  • 热Key问题及其解决方案:Redis高并发场景下的性能优化
  • 因子分析学习介绍,及其高阶应用以及学术上创新方向,鲁棒因子分析建模
  • [ACM_3] n组数据 | getchar() | getline(cin,s)
  • 代码重构学习
  • 塔能物联运维:成功打破物联网设备之间的互联互通难题
  • 蓝桥杯备赛学习笔记:高频考点与真题预测(C++/Java/python版)
  • Java 中序列化和反序列化
  • C语言【模仿strcpy】
  • kkFileView的安装和使用
  • fabric test-network启动
  • RAI Toolbox详解
  • 同一个网段下内网机器通过转发网络到堡垒机来访问外网的方式
  • Java进阶版线程池(超详细 )
  • TorchServe部署模型-index_to_name.json
  • 硕日新能SRNE Solar 荣获 TÜV NORD 目击实验室认可资质!
  • 免费制作头像的网站/网域名解析ip查询
  • 建立网站费用较低/谷歌引擎搜索
  • 乌鲁木齐做网站哪家好/百度搜索指数是怎么计算的
  • 上海优化网站价格/做网站优化的公司
  • 做网站需要ps吗/怎么在百度发布免费广告
  • 做企业网站前期需要准备什么/seo技巧与技术