java双括弧初始化

双括号语法解析
01. Map map = new HashMap() {{
02. put( "Name" , "Unmi" );
03. put( "QQ" , "1125535" );
04. }};
05.
06. List stooges = new ArrayList() {{
07. add( "Larry" );
08. add( "Moe" );
09. add( "Curly" );
10. }};


看起来都是在一条语句里完成,而不需要分步骤写成:

1. Map map = new HashMap();
2. map.put( "Name" , "Unmi" );
3. map.put( "QQ" , "1125535" );


一 不小心没好好理解的人可能以为它是什么特别的语法,关键是大括号连一块了,原作者也是在故作姿态,美其名曰:双括弧语法(double-brace syntax)。真是乱花渐欲迷人眼,其实就是匿名类加初始块。该文有解释:第一层括弧 实际是定义了一个内部匿名类 (Anonymous Inner Class),第二层括弧 实际上是一个实例初始化块 (instance initializer block),这个块在内部匿名类构造时被执行。

那怎么去更好理解它呢?如果我们写成如下的方式应该会更好理解吧,提个技巧,在 Eclipse 中对第一段代码按下 Ctrl + Shift + F 就如下了:

1. Map map = new HashMap() {
2. {
3. put( "Name" , "Unmi" );
4. put( "QQ" , "1125535" );
5. }
6. };


其 实就是匿名类啊,会创建出一个 HashMap 的子类来,匿名类中一个 {} 括起来的初始化块,里面自然可放置初始化代码。{} 块中的代码编译后会放到 <init>(),也就是构造方法中去,所以可用来初始化实例。如果是写在 TestDoubleBrace 类中,编译后你会看到会生成 TestDoubleBrace$1.class 文件,反编译该文件内容是:

01. final class com.unmi.TestDoubleBrace$1 extends java.util.HashMap{ //创建了一个 HashMap 的子类 TestDoubleBracke$1
02. com.unmi.TestDoubleBrace$1();
03. Code:
04. 0: aload_0
05. 1: invokespecial #8; //Method java/util/HashMap."<init>":()V //{} 中的代码放到了构造方法中去了
06. 4: aload_0
07. 5: ldc #10; //String Name
08. 7: ldc #12; //String Unmi
09. 9: invokevirtual #14; //Method put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
10. 12: pop
11. 13: aload_0
12. 14: ldc #18; //String QQ
13. 16: ldc #20; //String 1125535
14. 18: invokevirtual #14; //Method put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
15. 21: pop
16. 22: return
17.
18. }


所以说白了,什么双括弧语法啊,就是代码写得不规范,才使得那么的令人费解。如果还不能理解,再列两个惯用代码来:

01. JFrame frame = new JFrame();
02. frame.addMouseListener( new MouseAdapter() {
03. public void mouseClicked(MouseEvent e) {
04. // do womething here.
05. }
06. });
07.
08. Thread thread = new Thread() {{ // 也学着样把大括号也连一块写了
09. this .setName( "作业处理线程" );
10. } // 如果不重新定义 run() 方法,那么后面那个大括号也能与这个并一块
11.
12. public void run() {
13. // do something here.
14. }
15. };
16. thread.start();


应该没问题了吧,上面是事件监听器和多线程常用的写法,如果他不把大括号连在一起,而是规范的写代码,相信您一开始也不会对所谓的 Double Brace Syntax 有太多的困惑。要说这种初始化方法运用到集合中还挺方便的,只是无端的多了些匿名类。

刚 开始我看到这种双括符写法也是把它奉若圣经,对它只一知半解,昨天在用 XStream 把一个对象生成 XML 文件时,其中有一个 List 属性,我就借用了这种双括符法来初始化元素,结果生成的 XML 文件走了样,原因是 XStream 的 Converter 能处理 ArrayList,但无法很好的处理生成的 ArrayList 的匿名子类。因此才回头认真的重新审视了一番这个所谓的双括符初始化语法。





参考:

http://www.iteye.com/topic/412868

http://www.blogjava.net/Unmi/archive/2009/08/12/290845.html

http://www.iteye.com/topic/418542
### Java初始化数组的方法 在 Java 编程语言中,数组是一种用于存储固定大小同类型元素的数据结构。以下是几种常见的 Java 数组初始化方法: #### 方法一:声明并分配内存空间 可以先声明一个数组变量,再为其分配内存空间。这种方式适用于运行时动态赋值的情况。 ```java int[] array; // 声明数组 array = new int[10]; // 分配长度为10的空间 ``` 这种方法仅创建了一个指定长度的整型数组,默认情况下会将所有元素初始化为 `0`[^1]。 --- #### 方法二:静态初始化(定义的同时赋初值) 如果已知数组的具体内容,则可以直接在定义时完成初始化。 ```java int[] array = {1, 2, 3, 4, 5}; // 静态初始化 ``` 此方式会在编译阶段自动计算数组长度,并将其设置为 `{}` 大括号内的元素数量[^2]。 --- #### 方法三:动态初始化(结合匿名数组) 当需要立即使用数组而无需单独命名时,可采用匿名数组的方式。 ```java // 使用匿名数组作为参数传递给函数 printArray(new int[]{6, 7, 8, 9, 10}); void printArray(int[] arr) { for (int num : arr) System.out.println(num); } ``` 这种技术特别适合于临时用途或简化代码逻辑[^3]。 --- #### 方法四:混合模式——先声明后填充具体数值 有时可能只知道数组尺寸但不确定具体内容,在这种情形下可以选择分两步走:第一步只设定容量;第二部逐一填充值进去。 ```java double[] numbers = new double[5]; numbers[0] = 1.1; numbers[1] = 2.2; numbers[2] = 3.3; numbers[3] = 4.4; numbers[4] = 5.5; ``` 上述例子展示的是精度浮点数类型的数组实例化过程。 --- #### 注意事项 - 如果尝试访问未显式赋予新值得位置,那么它会被设成对应数据类型的默认零状态(比如对于对象引用来说就是null)- 利用花括弧形式进行初始配置的时候不需要指明维度数目因为系统能够自行推断出来。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值