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

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

Set set = new HashSet<>();

set.add(1);

set.add(2);

set.add(3);

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

private static final Set set = new HashSet<>();

static {

set.add(1);

set.add(2);

set.add(3);

}

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

Set set = new HashSet() {{

add(1);

add(2);

add(3);

}};

或是在接收集合作为输入的函数中直接初始化:

someFunction(new HashSet() {{

add(1);

add(2);

add(3);

}}

);

语法解读

事实上,如下双大括号初始化Set的代码

Set set = new HashSet() {{

add(1);

add(2);

add(3);

}};

是以下这段代码的改写:

Set set = new HashSet() {

{

add(1);

add(2);

add(3);

}

};

改写之后的代码就非常容易理解了。显然这是在HashSet的构造器中写了一个匿名内部类,这个匿名内部类含有一个实例初始化块,初始化块的内容是三个add()函数,向被初始化的this指向的HashSet中添加了三个元素。

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

利用双大括号初始化集合从效率上来说可能不如标准的集合初始化步骤。原因在于使用双大括号初始化会导致内部类文件的产生,而这个过程就会影响代码的执行效率。

例如如下代码:

// Double brace initialization

class Test1 {

public static void main(String[] args) {

long st = System.currentTimeMillis();

Set set0 = new HashSet() {{

add(1);

add(2);

}};

Set set1 = new HashSet() {{

add(1);

add(2);

}};

/* snip */

Set set999 = new HashSet() {{

add(1);

add(2);

}};

System.out.println(System.currentTimeMillis() - st);

}

}

// Normal initialization

class Test2 {

public static void main(String[] s) {

long st = System.currentTimeMillis();

Set set0 = new HashSet();

set0.add(1);

set0.add(2);

Set set1 = new HashSet();

set1.add(1);

set1.add(2);

/* snip */

Set set999 = new HashSet();

set999.add(1);

set999.add(2);

System.out.println(System.currentTimeMillis() - st);

}

}

用javac命令compile第一段代码会产生1000个.class文件,如下所示:

Test1$1.class

Test1$2.class

...

Test1$1000.class

同时从程序输出的运行时间来看, 双大括号初始化也显著慢于普通初始化的代码。差值大约在100ms左右。

java 两个大括号_Java中的双大括号初始化相关推荐

  1. Java双大括号_什么是Java中的双BRACE初始化?

    不负相思意 每当有人使用双支撑初始化时,小猫就会被杀死.除了语法非常不寻常而且不太地道(当然,品味是有争议的)之外,您还不必要地在应用程序中创建了两个重要的问题,我最近在博客上更详细地描述了.1.你创 ...

  2. java 循环new对象_java中new一个对象放在循环体里面与外面的区别

    首先说下问题: 这次在做项目的是出现了一个new对象在循环里面与外面造成的不同影响. 大家可以看到这个new的对象放在不同的位置产生的效果是不一样的. 经过多方查询与验证可以得出结论: * EasyU ...

  3. Java生成随机数原理_Java中随机数的产生方式与原理详解

    Java中随机数的产生方式与原理 查阅随机数相关资料,特做整理 首先说一下java中产生随机数的几种方式 在j2se中我们可以使用Math.random()方法来产生一个随机数,这个产生的随机数是0- ...

  4. Java 细节汇总(4)-Arrays 中的双轴快排

    文章目录 1. Arrays 中的双轴快排 2. Java 中 switch 支持字符串的原理 3. Java 中 break,continue 标签的用法 4. Java 中 Math.ceil() ...

  5. java可以多重继承吗_Java中的多重继承与组合vs继承

    java可以多重继承吗 有时我写了几篇有关Java继承,接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后了解组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能 ...

  6. java中有没有栈_Java中堆和栈有什么区别

    stack 和 heep 都是内存的一部分stack 空间小,速度比较快, 用来放对象的引用heep 大,一般所有创建的对象都放在这里.栈(stack):是一个先进后出的数据结构,通常用于保存方法(函 ...

  7. java 向上取整_java 中的异常处理和常用类使用

    一.异常: 1.异常的简单介绍: Throwable类 / Error Exception | | Unchecked Checked Runtime Exception Exception Exce ...

  8. java 基本类型 引用_java中 引用类型 和 基本类型 有何区别?

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newa ...

  9. java构造器详解_Java中关于构造器的使用详解

    这篇文章主要介绍了Java构造器使用方法及注意事项的相关资料,这里举例说明如何使用构造器及需要注意的地方,需要的朋友可以参考下 Java构造器使用方法及注意事项 超类的构造器在子类的构造器运行之前运行 ...

最新文章

  1. 编译 android 内核,编译内核  |  Android 开源项目  |  Android Open Source Project
  2. 文献学习(part15)--Subspace Clustering via Good Neighbors
  3. 最小路径问题_BFS
  4. 你还在生产环境改代码么?函数计算版本管理(三)使用别名进行灰度发布...
  5. iperf3怎么看结果_iperf3命令使用
  6. VOS2009_2.1.2.0的安装教程
  7. Hexo博客向百度提交链接
  8. C#语言自定义平方根函数
  9. web浏览器和web服务器的协议是,浏览器是如何与Web服务器进行通信的
  10. mongodb for mac安装
  11. 码云上最棒的Java管理后台系统
  12. html表单元素占位符是,HTML各种表单元素模板及写法
  13. 如何将xlsx表格文件转换成txt文件?
  14. Excel函数--SUM计算累计销量
  15. c++奇怪的1179链接错误
  16. 阿里妈妈佣金转换API接口(item_id-佣金转换)接口代码对接教程
  17. 没有网线的时候怎么让虚拟机使用Windows的wifi上网设置
  18. 白杨SEO:网站外链如何做?增加外链的42个技巧方法
  19. 企业如何利用网络趋势做好线上营销?
  20. 【OpenCV 例程300篇】204. 图像的色彩风格滤镜

热门文章

  1. 垄断竞争市场和寡头垄断市场中生产者的行为
  2. Acala 月报| 上线一周节点破百,Mandala测试网糖果节即将开启
  3. Java帝国之安全争斗
  4. 曼昆《经济学原理》第一二章部分
  5. 《中华大字库》版权声明
  6. 旺旺聊天记录解码(转PEDIY)
  7. iPhone发送彩信详细图文指导教程
  8. Python教程分享,10款超好用的Python开发工具!
  9. ASCII码及扩展码参考
  10. 我的世界java额外参数_我的世界是如何在命令方块中附加参数方法