最近在阅读Mybatis源码的时候,看到了一种原来很少见到的语法:

public class RichType {

  ...

  private List richList = new ArrayList() {
{
add("bar");
}
}; }

查了一下资料,补足了自己的一个知识盲区,嘻嘻。

一. 什么是Java双大括号初始化?

通常情况下,初始化Java集合并向其中添加几个元素的步骤如下:

public class RichType {

  ...

  private List richList;

  public RichType(){
richList = new ArrayList();
richList.add("bar");
} }

或者我们可以在静态初始化块中向作为静态变量的集合添加元素:

public class RichType {

  ...

  private static List richList = new ArrayList();

  static{
richList.add("bar");
} }

从语法上来看,这样的初始化方法虽然格式清晰明了,但语法上略显冗余。事实上,Java允许一种精简的双大括号初始化方法:

List richList = new ArrayList() {
{
add("bar");
}
};

二. 语法解读

实际上上述语法可以拆为两个部分,第一部分是创建了一个继承于ArrayList的匿名内部类:

List richList = new ArrayList() {

};

第二部分,是在匿名内部类中指定了一个初始化块,并在初始化块中调用对象本身的add方法添加元素:

List richList = new ArrayList() {
{
add("bar");
}
};

这里需要回顾一下类的初始化方式,在Java中一个类和实例的初始化可以有三种方式:

  • 静态初始化块:静态初始化块只在类加载时执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。
  • 初始化块:非静态初始化块在每次初始化实例对象的时候都执行一次,可以给任意变量赋值。
  • 构造方法:在每次初始化实例对象时调用。

初始化块的顺序

  1. 在加载类时执行一次静态初始化块(之后不再调用)。
  2. 在每次初始化实例对象时:先执行非静态初始化块,
  3. 再执行构造方法。

三. 效率问题和产生的.class文件结构

利用双大括号初始化集合从效率上来说可能不如标准的集合初始化步骤。原因在于使用双大括号初始化会导致内部类文件的产生,而这个新的.class文件产生就会导致需要再次进行类加载的操作,会影响最终效率。

Java中双括号初始化是个什么操作的更多相关文章

  1. Java map双括号初始化方式的问题

    关于Java双括号的初始化凡是确实很方便,特别是在常量文件中,无可替代.如下所示: Map map = new HashMap() { { put("Name", "Un ...

  2. Java:双括号初始化 /匿名内部类初始化法

    偶然见到一种初始化方式,感到十分新奇: //新建一个列表并赋初值A.B.C ArrayList<String> list = new ArrayList<String>() { ...

  3. Java中的成员初始化顺序和内存分配过程

    Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...

  4. Java中数组的初始化方式

    Java中数组的初始化方式    初始化方式有两种: 1.静态初始化:初始化时由程序猿显式指定每一个数组元素的初始值,由系统指定数组长度 2.动态初始化:初始化时由程序猿仅仅指定数组长度,由系统为数组 ...

  5. java中的静态初始化块

    Java 中可以通过初始化块进行数据赋值.如: 在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块.如果使用 static 修饰初始化块,就称为静态初始化块. 需要特别注意: ...

  6. java中replaceAll反斜杠\ or java中replaceAll 括号[

    java中replaceAll反斜杠\   String s=new String("this is a \\"); s.replaceAll("\\",&qu ...

  7. Java中list如何利用遍历进行删除操作

    转: Java中list如何利用遍历进行删除操作 2018年03月31日 10:23:41 Little White_007 阅读数:3874   Java三种遍历如何进行list的便利删除: 1.f ...

  8. java中对对象进行判空的操作--简洁编码

    java中对对象进行判空的操作 首先来看一下工具StringUtils的判断方法: 一种是org.apache.commons.lang3包下的: 另一种是org.springframework.ut ...

  9. 关于JAVA中string直接初始化赋值和new的区别,是否可以联系到int[]的情况

    String str1 = "ABC"; String str2 = new String("ABC"); String str1 = “ABC”;可能创建一个 ...

  10. java中对象产生初始化过程

    以前面试的时候,很多公司的笔试题中有关new一个对象有关一系列初始化的过程的选择题目.请看下面的题目. class Parent { static { System.out.println(" ...

随机推荐

  1. Mac 修改版本号

    修改版本号 在安装某些软件(XCode)的过程中, 系统会提示版本低,需要升级到高版本, 而很多人不想升级而需要安装这些软件, 此时只需将版本号修改成软件安装要求的版本号就可以了. 由于SystemV ...

  2. docker 应用篇————es[八]

    前言 简单介绍一下es镜像. 正文 首先安装一下: elasticSearch. 启动一下: 然后就可以访问了. 使用一下docker stats 然后你就发现了这个docker 容器启动的时候要1. ...

  3. threading的定时器模块,python,每间隔一段时间执行一次任务

    工作中常有一些定时任务要处理,比如使用百度的接口,它的access_token是一个更新一次的,每次使用时总是请求会很慢,所以我们把它保存起来,用定时器模块,定时在过期之前请求一次,或者定时数据同步, ...

  4. mac版本vscode窗口崩溃crashed

    1.截图 出现时机 当安装依赖的时候大概率会出现,甚至安装一次依赖会出现几次 解决 具体原因未知 重新启动电脑以及退出软件都不能解决 去官网重新下载,重新安装问题解决

  5. 力扣190(java)-颠倒二进制位(简单)

    题目: 颠倒给定的 32 位无符号整数的二进制位. 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型.在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论 ...

  6. 基于IoT全链路实时质量-魔洛哥

    简介: 通过基于IoT的全链路实时质量,业务使用狄仁杰进行全链路埋点后,可一键接入魔洛哥平台,实现终端问题的实时感知和链路分析,以及智能终端系统业务场景的全链路实时质量.整体方案接入成本低(分钟级别接 ...

  7. 我们为什么要做 SoloPi

    SoloPi现状 去年(2019年)7月份,蚂蚁集团正式对外开源了客户端自动化测试工具 SoloPi ,其主要包括三大模块:录制回放(用于功能测试).性能工具(用于性能测试)以及一机多控(服务于兼容性 ...

  8. 基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台

    简介: 本文将对 RocketMQ-Exporter 的设计实现做一个简单的介绍,读者可通过本文了解到 RocketMQ-Exporter 的实现过程,以及通过 RocketMQ-Exporter 来 ...

  9. RocketMQ 千锤百炼--哈啰在分布式消息治理和微服务治理中的实践

    简介: 随着公司业务的不断发展,流量也在不断增长.我们发现生产中的一些重大事故,往往是被突发的流量冲跨的,对流量的治理和防护,保障系统高可用就尤为重要. 作者|梁勇 ​ 背景 ​哈啰已进化为包括两轮出 ...

  10. CNCF TOC 委员张磊:不断演进的云原生给我们带来了什么?

    简介: 任何一种云原生技术,它不再是某种能力的弥补,而是更多地将云的能力以某种方式更简单.更高效地透出给我的应用去使用.无论是容器.K8s 还是 Service Mesh,他们都是在不同的环节帮助应用 ...