关于Java双括号的初始化凡是确实很方便,特别是在常量文件中,无可替代。如下所示:

Map map = new HashMap() {
  {
  put("Name", "Unmi");
  put("QQ", "1125535");
  }
};

好处很明显就是一目了然。这里来罗列下此种方法的坏处,如果这个对象要串行化,可能会导致串行化失败。

1.此种方式是匿名内部类的声明方式(不懂的下文有详尽解释),所以引用中持有着外部类的引用。所以当时串行化这个集合时外部类也会被不知不觉的串行化,当外部类没有实现serialize接口时,就会报错。

2.上例中,其实是声明了一个继承自Hashset的子类。然而有些串行化方法,例如要通过Gson串行化为json,或者要串行化为xml时,类库中提供的方式,是无法串行化Hashset或者HashMap的子类的,从而导致串行化失败。解决办法:重新初始化为一个Hashset对象:

new HashMap(map);

这样就可以正常初始化了。

双括号写法的原理:

第一层括弧 实际是定义了一个内部匿名类 (Anonymous Inner Class),第二层括弧 实际上是一个实例初始化块
(instance initializer
block),这个块在内部匿名类构造时被执行。这个块之所以被叫做“实例初始化块”是因为它们被定义在了一个类的实例范围内。

上面代码如果是写在 TestDoubleBrace 类中,编译后你会看到会生成 TestDoubleBrace$1.class 文件,反编译该文件内容是:

final class com.unmi.TestDoubleBrace$1 extends java.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
}

Java map双括号初始化方式的问题的更多相关文章

  1. Java:双括号初始化 /匿名内部类初始化法

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

  2. Java中数组的初始化方式

    Java中数组的初始化方式    初始化方式有两种: 1.静态初始化:初始化时由程序猿显式指定每一个数组元素的初始值,由系统指定数组长度 2.动态初始化:初始化时由程序猿仅仅指定数组长度,由系统为数组 ...

  3. Java Map的正确使用方式

    原文:https://www.liaoxuefeng.com/article/1256136507802816 正确使用Map,只需要正确实现hashCode()和equals()就行了吗? 恐怕还不 ...

  4. Java技巧之双括弧初始化

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

  5. java中Map和List初始化的两种方法

    第一种方法(常用方法): //初始化List List<string> list = new ArrayList</string><string>(); list. ...

  6. java基础-Map的静态初始化以及Map的遍历等.....................

    1.map的静态初始化,以及map遍历的几种方法: package com.cy.test; import java.util.HashMap; import java.util.Iterator; ...

  7. Java Collection - 遍历map的几种方式

    作者:zhaoguhong(赵孤鸿) 出处:http://www.cnblogs.com/zhaoguhong/ 本文版权归作者和博客园共有,转载请注明出处 ---------------- 总结 如 ...

  8. Java遍历Map的3种方式

    package test; import java.util.Collection; import java.util.HashMap; import java.util.Map; import ja ...

  9. java 遍历Map的四种方式

      java 遍历Map的四种方式 CreationTime--2018年7月16日16点15分 Author:Marydon 一.迭代key&value 第一种方式:迭代entrySet 1 ...

随机推荐

  1. rpm基本命令参考

    水可载舟,亦可覆舟! 1. 介绍 在Linux操作系统中,常用的软件有RPM包软件包,src.rpm格式的软件包(源码),以源代码发布的软件包以及.bin格式软件包和绿色软件.如果采用.rpm格式的软 ...

  2. ntp时钟同步

    服务器时间的一致性,很关键的. 11. 基于ntp服务的形式 [root@server0 ~]# yum -y install chrony   //NTP客户端    centos7.x  cent ...

  3. Win10易升-在线升级工具

    Win7盗版激活,直接用win10官方推荐的工具在线升级W10直接升级为正版用户... 00.升级协议 11.兼容检测 22.工具下载 Window10官方在线升级工具:https://pan.bai ...

  4. Ubuntu与Windows7双系统下, 系统时间不一致的问题

    Ubuntu使用的UTC时间, 而Windows使用的是Local Time, 就导致每次切换系统后, Windows时间都会正好晚8个小时. 有两种解决办法, 一个是修改Ubuntu, 另一个是修改 ...

  5. 数学之路-python计算实战(9)-机器视觉-图像插值仿射

    插值 Python: cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) → dst interpolation – interpol ...

  6. 【php页面表单提交】form校验后再提交,非ajax提交

    form表单校验后,在执行提交动作: <form method="post" action="{:U('Custom/addmsg')}" id=&quo ...

  7. IBatis.Net 视频教程 原创教程

    IBatis.Net 视频教程 列文件:共21个 Ibatis.Net 第01课 了解 和下载.avi Ibatis.Net 第02课 搭建简单三层项目 引入Ibatis.avi ibatis.net ...

  8. Kubernetes滚动更新介绍及使用-minReadySeconds

    滚动升级Deployment 现在我们将刚刚保存的yaml文件中的nginx镜像修改为 nginx:1.13.3,然后在spec下面添加滚动升级策略:   1 2 3 4 5 6 7 minReady ...

  9. java 下对字符串的格式化

    1.对整数进行格式化:%[index$][标识][最小宽度]转换方式         我们可以看到,格式化字符串由4部分组成,其中%[index$]的含义我们上面已经讲过,[最小宽度]的含义也很好理解 ...

  10. Linux按照CPU、内存、磁盘IO、网络性能监测【转载】

    本文转载地址:https://my.oschina.net/chape/blog/159640 系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监 ...