原文地址:http://www.c2.com/cgi/wiki?DoubleBraceInitialization

原作者:不详

译者:Alan Gao @ cgaolei.iteye.com

译者序:这是我在JavaIdioms(http://www.c2.com/cgi/wiki?JavaIdioms)上看到一个Java使用技巧。使用Java这么多年了,也还是头一次看到,还很实用。别看这小技巧好像很简单,但保证你不会在任何一书Java教材上看到,因为它不是一个真正的语法规范,而是一个语法的用法变种。小技巧还蕴含着Java的深层知识,就是身经百战的老手也不一定能说出其中奥妙。

翻译正文:

由于Java语言的集合框架中(collections, 如list, map, set等)没有提供任何简便的语法结构,这使得在建立常量集合时的工作非常繁索。每次建立时我们都要做:

  1. 定义一个临时的集合类变量
  2. 建立一个空集合的实例,然后赋值给变量
  3. 将数据放入集合中
  4. 最后将集合做为参数传递给方法

例如,要将一个Set变量传给一个方法:

Java代码  
  1. Set<String> validCodes = new HashSet<String>();
  2. validCodes.add("XZ13s");
  3. validCodes.add("AB21/X");
  4. validCodes.add("YYLEX");
  5. validCodes.add("AR2D");
  6. removeProductsWithCodeIn(validCodes);

也可以用静态初始的方法

Java代码  
  1. private static final Set<String> validCodes = new HashSet<String>();
  2. static {
  3. validCodes.add("XZ13s");
  4. validCodes.add("AB21/X");
  5. validCodes.add("YYLEX");
  6. validCodes.add("AR2D");
  7. }

其实,还有简结的方法,我们可以用双括弧语法(double-brace syntax)建立并初始化一个新的集合:

Java代码  
  1. private static final Set<String> VALID_CODES = new HashSet<String>() {{
  2. add("XZ13s");
  3. add("AB21/X");
  4. add("YYLEX");
  5. add("AR2D");
  6. }};

或者

Java代码  
  1. removeProductsWithCodeIn(new HashSet<String>() {{
  2. add("XZ13s");
  3. add("AB21/X");
  4. add("YYLEX");
  5. add("AR5E");
  6. }});

第一层括弧 实际是定义了一个内部匿名类 (Anonymous Inner Class),第二层括弧 实际上是一个实例初始化块 (instance initializer block),这个块在内部匿名类构造时被执行。这个块之所以被叫做“实例初始化块”是因为它们被定义在了一个类的实例范围内。这和“静态初始化块 (static initialzer)”不同,因为这种块在定义时在括弧前使用了static关键字,因此它的和类在同一个范围内的,也就是说当类加载时就会被执行(更详情,可参考Java语言规范http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6 )。实例初始化块中可以使用其容器范围内的所有方法及变量,但特别需要注意的是实例初始化块是在构造器之前运行的。

这种方法只适用于不是final的类,因为final类是无法建立内部匿名子类,好在集合类都没有这个限制。因此,这种方法还可以被用来初始化其它任何对象,比如一个GUI对象:

Java代码  
  1. add(new JPanel() {{
  2. setLayout(...);
  3. setBorder(...);
  4. add(new JLabel(...));
  5. add(new JSpinner(...));
  6. }});

这样建立的内部匿名类的实例中包函它容器对像的引用。如果串行化(serialization)这个集合同时也会串行化它的外部类。

Java技巧之双括弧初始化相关推荐

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

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

  2. java括号用法_Java双括弧使用技巧

    Java双括弧技巧回顾 初看cgaolei翻译的Java技巧之双括弧初始化一文,走马观花,只知用法,未细看后面的解释.蔚为惊艳,心里想Java竟然有这么神奇的语法而一直未得知.因为在初始化集合时确实方 ...

  3. java 两个大括号_Java中的双大括号初始化

    什么是Java双大括号初始化? 通常情况下,初始化Java集合并向其中添加几个元素的步骤如下: Set set = new HashSet<>(); set.add(1); set.add ...

  4. java 匿名初始化_Java:双括号初始化 /匿名内部类初始化法

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

  5. Java的懒汉式双检锁单例模式

    Java的懒汉式双检锁单例模式 文章目录 Java的懒汉式双检锁单例模式 一. 实现一个双检锁 二. 为什么线程不安全 三. 关于指令重排序 四. 关于原子操作 五. 实现线程安全的双检锁 首先回忆一 ...

  6. php键顺序初始化,Java类中各成员初始化的顺序

    了解Java中类各个成员的初始化顺序是非常重要的,这样你可以对类有全局的认识.不说太多,直接看下面的例子 class Father { static{ System. out.println(&quo ...

  7. Java类和对象的初始化顺序

    本文摘录于http://blog.csdn.net/socoolfj/archive/2006/05/23/750425.aspx,并修改例子的代码,加上自己的见解. 类装载步骤 在Java中,类装载 ...

  8. (002) java后台开发之对象初始化

    class Default{ boolean t;char c;byte b;short s;int i;long l;float f;double d;public void show() {Sys ...

  9. Java 父类子类的对象初始化过程

    转载自 Java 父类子类的对象初始化过程 摘要: Java基本的对象初始化过程,子类的初始化,以及涉及到父类和子类的转化时可能引起混乱的情况. 1. 基本初始化过程: 对于一个简单类的初始化过程是: ...

最新文章

  1. Java抽象类和接口
  2. boost::sort模块实现字符串排相关的测试程序
  3. Web前端笔试面试题汇总(转自github)
  4. kotlin 查找id_Kotlin程序查找圆柱体区域
  5. 求π的值(信息学奥赛一本通-T1156)
  6. Java Servlet response
  7. 领导秘书,一般都是什么样的人?
  8. 阿里将开源进行到底!
  9. 英语语料库与英文写作
  10. 金融二叉树模型-给期权定价
  11. Don’t Just Assume; Look and Answer: Overcoming Priors for Visual Question Answering——论文阅读笔记
  12. 递归求平均数|理解|讲解| c语言
  13. 华东理工某ACMer总结
  14. [转](42)驱动中使用全局变量
  15. 成交量占比过半 优信拍继续领跑二手车电商B端市场
  16. Docker 启动 MySQL 最佳实践
  17. python自相关函数提取基音周期_自相关函数法基音周期提取(matlab版)
  18. win10打印机共享问题集,及解决方法持续更新
  19. java的prefetch()_聊聊FluxFlatMap的concurrency及prefetch参数
  20. android 独立插件,最新反编译任何微信小程序,以及独立分包、插件的处理方式...

热门文章

  1. java.lang.RuntimeException: Parcel: unable to marshal value com.
  2. C++ fabs和abs区别
  3. poj_1363_Rai
  4. 1055: 兔子繁殖问题 这是一个有趣的古典数学问题,著名意大利数学家Fibonacci曾提出一个问题:有一对小兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。
  5. Fedora 24 Linux 环境下实现 Infinality 字体渲染增强及 Java 字体渲染改善的方法(修订)...
  6. 自动驾驶(三十四)---------可行驶区域检测
  7. 共模电感 | 磁芯选型
  8. 鸿蒙系统比苹果系统还快,任正非揭秘!华为鸿蒙系统,比安卓、苹果系统快,为物联网而生...
  9. 《沈剑架构师训练营》第6章 - 缓存架构
  10. ubuntu 板载r8125有限网卡连接