最近在阅读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. 数据库自增ID用完了会怎么样?

    记一个数据库方面的面试题:数据库自增ID用完了会怎么样? MySQL中 int 类型是4个字节,如果是有符号,那就是 [ -2^31 , 2^31-1 ], 如果是无符号,那就是 [ -2^31 , ...

  2. HarmonyOS实现几种常见图片点击效果

    一. 样例介绍 HarmonyOS提供了常用的图片.图片帧动画播放器组件,开发者可以根据实际场景和开发需求,实现不同的界面交互效果,包括:点击阴影效果.点击切换状态.点击动画效果.点击切换动效. 相关 ...

  3. Mysql之刷盘机制

    一.刷盘机制总览 刷盘过程 mysql刷脏数据在写redo之后,逻辑跟oracle一致. checkpoint/commit -> 内存中的redo到redolog文件 -> 内存中的脏数 ...

  4. GAN的实现和一些问题

    GAN的学习是一个二人博弈问题,最终目标是达到纳什平衡.对抗指的是生成网络和判别网络的互相对抗.生成网络尽可能生成逼真样本,判别网络则尽可能去判别该样本是真实样本,还是生成的假样本.示意图如下: 生成 ...

  5. docker 应用篇————dockerfile[十四]

    前言 简单介绍一下dockerfile. 正文 dockerfile就是docker image的构建文件. 然后来运行一下. 然后就产生了test:1.0 这个镜像. 然后启动一下你就发现了这个镜像 ...

  6. 重新点亮linux 命令树————rpm软件包管理[十一七]

    前言 简单介绍一下软件管理 正文 软件包管理器 rpm 包和rpm 命令 yum 仓库 源代码编译安装 内核升级 grub配置文件 软件包管理器: 包管理器是为了方便软件安装.卸载,解决软件依赖关系的 ...

  7. 第一次blog

    前言:我在大一上学期学习了c语言,然后在下学期学习了第二门语言java,因为之前c语言学的挺一般的,然后在这学期学习java感觉还是挺不简单的,要自学很多东西,在这段时间里,我学习了JAVA的基本语法 ...

  8. Mac搭建appium环境及python运行代码示例

    Appium主要是通过调用安卓提供的接口来执行命令的,所以需要安装Java和安卓SDK. 1.安装Appium服务端 appium的服务端是基于node的,直接使用npm(node包管理器)安装即可, ...

  9. 免费体验!阿里云智能LOGO帮你解决设计难题

    ​简介:超实用!零基础搞定一个高大上的智能logo设计 新年过后,往往是大家一年中士气最足的时候,散去了年末的疲惫和emo,重燃对新一年的热情和希望. 想创业的朋友们同样意气风发,趁着新年的劲头想大干 ...

  10. [GPT] 网页中某些dom内容是通过 js 数据异步渲染的,nodejs 怎么获取网页解析这些数据

      要处理使用JavaScript异步渲染内容的网页,您可以在 JavaScript 蜘蛛中使用 Puppeter 或 Playwright 等无头浏览器来获取网页,然后与动态渲染的内容进行交互. 下 ...