关于Java双大括号{{}}的具体使用
作者:人形bug制造机9527 发布时间:2021-05-28 16:32:01
初看 cgaolei 翻译的 Java技巧之双括弧初始化 一文,走马观花,只知用法,未细看后面的解释。蔚为惊艳,心里想 Java 竟然有这么神奇的语法而一直未得知。因为在初始化集合时确实方便不少。原来做某些测试要初始化集合时会用到 commons-lang 包和 JDK 的 Arrays 工具类,现在知道可以这么用了:
Map map =newHashMap() {{
put("Name","Unmi");
put("QQ","1125535");
}};
List stooges =newArrayList() {{
add("Larry");
add("Moe");
add("Curly");
看起来都是在一条语句里完成,而不需要分步骤写成:
Map map =newHashMap();
map.put("Name","Unmi");
map.put("QQ","1125535");
一不小心没好好理解的人可能以为它是什么特别的语法,关键是大括号连一块了,原作者也是在故作姿态,美其名曰:双括弧语法(double-brace syntax)。真是乱花渐欲迷人眼,其实就是匿名类加初始块。该文有解释:***层括弧 实际是定义了一个内部匿名类 (Anonymous Inner Class),第二层括弧 实际上是一个实例初始化块 (instance initializer block),这个块在内部匿名类构造时被执行。
那怎么去更好理解它呢?如果我们写成如下的方式应该会更好理解吧,提个技巧,在 Eclipse 中对***段代码按下 Ctrl + Shift + F 就如下了:
Map map =newHashMap() {
{
put("Name","Unmi");
put("QQ","1125535");
}
};
其实就是匿名类啊,会创建出一个 HashMap 的子类来,匿名类中一个 {} 括起来的初始化块,里面自然可放置初始化代码。{} 块中的代码编译后会放到 (),也就是构造方法中去,所以可用来初始化实例。如果是写在 TestDoubleBrace 类中,编译后你会看到会生成 TestDoubleBrace$1.class 文件,反编译该文件内容是:
finalclasscom.unmi.TestDoubleBrace$1extendsjava.util.HashMap{//创建了一个 HashMap 的子类 TestDoubleBracke$1
com.unmi.TestDoubleBrace$1();
Code:
0: aload_0
1: invokespecial #8;//Method java/util/HashMap."":()V //{} 中的代码放到了构造方法中去了
4: aload_0
5: ldc #10;//String Name
7: ldc #12;//String Unmi
9: invokevirtual #14;//Method put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
12: pop
13: aload_0
14: ldc #18;//String QQ
16: ldc #20;//String 1125535
18: invokevirtual #14;//Method put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
21: pop
22:return
}
所以说白了,什么双括弧语法啊,就是代码写得不规范,才使得那么的令人费解。如果还不能理解,再列两个惯用代码来:
JFrame frame =newJFrame();
frame.addMouseListener(newMouseAdapter() {
publicvoidmouseClicked(MouseEvent e) {
// do womething here.
}
});
Thread thread =newThread() {{// 也学着样把大括号也连一块写了
this.setName("作业处理线程");
}// 如果不重新定义 run() 方法,那么后面那个大括号也能与这个并一块
publicvoidrun() {
// do something here.
};
thread.start();
应该没问题了吧,上面是事件 * 和多线程常用的写法,如果他不把大括号连在一起,而是规范的写代码,相信您一开始也不会对所谓的 Double Brace Syntax 有太多的困惑。要说这种初始化方法运用到集合中还挺方便的,只是无端的多了些匿名类。
刚开始我看到这种Java双括弧写法也是把它奉若圣经,对它只一知半解,昨天在用 XStream 把一个对象生成 XML 文件时,其中有一个 List 属性,我就借用了这种双括符法来初始化元素,结果生成的 XML 文件走了样,原因是 XStream 的 Converter 能处理 ArrayList,但无法很好的处理生成的 ArrayList 的匿名子类。因此才回头认真的重新审视了一番这个所谓的双括符初始化语法。
来源:https://blog.csdn.net/m0_49194578/article/details/125850839


猜你喜欢
- 在Android开发中,我们经常使用列表控件,而有时候列表控件条目中又会是多条目数据,这时候,我们无法确定每个条目的数据多少,而为了美观,我
- 开发中最让人头疼的是应用突然 * ,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误
- 1、mybatis-plus相信大家在日常的开发中用的最多的就是 mybatis-plus了吧,作为一个 MyBatis (opens ne
- 我们先假设一个场景想象一下,当一个项目出现bug的时候,恰巧这个时候需要你去修改,而当你打开项目之后,眼前的代码让你有一种特别严重的陌生感,
- 数字签名广泛用于保护PDF文档,可见数字签名在日常生活中是相当重要的。在这篇文章中我将与大家分享如何给PDF文件添加可见的数字签名。首先我下
- 一、前言关于EasyExcel,它对poi做了进一步的封装,使得整个编写流程更加的面向对象。好处嘛,我认为流程上更加清晰即易懂、可读性更好,
- 1、Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示:程序计数器:一块较小内存区域
- 简介redis 多数据源主要的运用场景是在需要使用多个redis服务器或者使用多个redis库,本文采用的是fastdep依赖集成框架,快速
- 本文实例为大家分享了java批量解析微信dat文件的具体代码,供大家参考,具体内容如下微信图片默认路径:C:\Users\b-eet\Doc
- 关于Android 6.0Android老版本网络请求:1,HttpUrlConnection2,Apache Http ClientAnd
- 项目中有个要求,对上传服务器的图片大小进行判断,大于500k的图片要进行压缩处理,让其小于500k后在上传。可以通过java api的Ima
- 如今,手机应用渗透到各行各业,数量难以计数,其中大多数应用都会使用到网络,与服务器的交互势不可挡,那么android当中访问网络有哪些方式呢
- classpath读取resources目录下文件最近在springboot+maven的项目中去读取资源文件的时候,报了找不到文件的错误。
- 工具/原料vs2005步骤/方法新建安装部署项目打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也
- Lambda 表达式最早接触到 Lambda 表达式的时候,是在学习 python 的时候,当时就很好奇。后来,才发现 Java 也有这个方
- 正常状态是UP,跳闸是⼀种状态CIRCUIT_OPEN,可以通过/health查看,前提是工程中需要引入SpringBoot的actuato
- 引言在实际应用场景中,我们封装一个学生的类,这个类用于封装学生的日常行为,如:上学、吃饭、上课等。然而,在疫情期间,学生上学时入校、吃饭时进
- 所以对于应用层用着还不是很方便。最近做一个项目顺便就封装了一个调用默认打印机的类。虽说有几个小bug,但对于目前来说,已经满足需求了。以后不
- 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。数组虽然也可以存
- OAuth 简介OAuth 是由 Blaine Cook、Chris Messina、Larry Halff 及 David Recordo