关于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

标签:Java,双大括号
0
投稿

猜你喜欢

  • Java中synchronized正确使用方法解析

    2021-12-20 13:00:39
  • Java 实现拦截器Interceptor的拦截功能方式

    2023-04-25 04:35:15
  • java(包括springboot)读取resources下文件方式实现

    2021-06-03 20:16:06
  • Spring Boot 2.X 快速集成单元测试解析

    2023-11-11 02:45:05
  • java使用正则表达校验手机号码示例(手机号码正则)

    2022-04-07 20:37:04
  • spring boot 实现配置多个DispatcherServlet最简单方式

    2023-12-18 03:24:46
  • 解析Java中的static关键字

    2022-03-02 17:15:35
  • 浅谈Java封装、继承、多态特性

    2023-10-09 13:59:35
  • Scala中的mkString的具体使用方法

    2023-11-16 00:18:18
  • SSM如何实现在Controller中添加事务管理

    2023-11-29 07:23:18
  • C#中 MessageBox的使用技巧

    2023-06-25 16:15:48
  • SpringBoot如何在运行时动态添加数据源

    2023-11-13 21:36:40
  • JPA多数据源分布式事务处理方案

    2023-08-09 03:50:06
  • 详解Spring Boot加载properties和yml配置文件

    2023-11-24 07:14:09
  • java中MultipartFile互转File的方法

    2022-12-14 16:52:09
  • 深入浅出MappedByteBuffer(推荐)

    2023-11-14 19:59:43
  • Intellij IDEA 2018配置Java运行环境的方法步骤

    2023-06-08 09:56:50
  • Java操作MongoDB模糊查询和分页查询

    2023-03-12 20:31:22
  • 简单了解Spring中BeanFactory与FactoryBean的区别

    2022-01-14 03:59:20
  • 使用SpringMVC访问Controller接口返回400BadRequest

    2023-06-05 00:14:01
  • asp之家 软件编程 m.aspxhome.com