Java map双括号初始化方式的问题
关于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双括号初始化方式的问题的更多相关文章
- Java:双括号初始化 /匿名内部类初始化法
		
偶然见到一种初始化方式,感到十分新奇: //新建一个列表并赋初值A.B.C ArrayList<String> list = new ArrayList<String>() { ...
 - Java中数组的初始化方式
		
Java中数组的初始化方式 初始化方式有两种: 1.静态初始化:初始化时由程序猿显式指定每一个数组元素的初始值,由系统指定数组长度 2.动态初始化:初始化时由程序猿仅仅指定数组长度,由系统为数组 ...
 - Java Map的正确使用方式
		
原文:https://www.liaoxuefeng.com/article/1256136507802816 正确使用Map,只需要正确实现hashCode()和equals()就行了吗? 恐怕还不 ...
 - Java技巧之双括弧初始化
		
由于Java语言的集合框架中(collections, 如list, map, set等)没有提供任何简便的语法结构,这使得在建立常量集合时的工作非常繁索.每次建立时我们都要做: 定义一个临时的集合类 ...
 - java中Map和List初始化的两种方法
		
第一种方法(常用方法): //初始化List List<string> list = new ArrayList</string><string>(); list. ...
 - java基础-Map的静态初始化以及Map的遍历等.....................
		
1.map的静态初始化,以及map遍历的几种方法: package com.cy.test; import java.util.HashMap; import java.util.Iterator; ...
 - Java Collection - 遍历map的几种方式
		
作者:zhaoguhong(赵孤鸿) 出处:http://www.cnblogs.com/zhaoguhong/ 本文版权归作者和博客园共有,转载请注明出处 ---------------- 总结 如 ...
 - Java遍历Map的3种方式
		
package test; import java.util.Collection; import java.util.HashMap; import java.util.Map; import ja ...
 - java 遍历Map的四种方式
		
java 遍历Map的四种方式 CreationTime--2018年7月16日16点15分 Author:Marydon 一.迭代key&value 第一种方式:迭代entrySet 1 ...
 
随机推荐
- 转:Irrlicht 0.1引擎源码分析与研究(一)
			
目录(?)[-] 主要技术特性 引擎概览 Irrlicht的窗口管理 Irrlicht引擎主要是由一个名叫Nikolaus Gebhardt奥地利人所设计,是sourceforge上的一个开源项目 ...
 - Mysql 将结果保存到文件 从文件里运行sql语句 记录操作过程(tee 命令的使用)
			
1. 有时候我们可能须要记录我们对mysql的操作过程,这时我们能够使用mysql的tee命令 1)第一种情况是在链接数据库的时候使用tee >mysql -u root -p --te ...
 - rc522头文件
			
//本头文件是以51为蓝本 #ifndef __rc522_h__ #define __rc522_h__ #include <string.h> #include <wiringP ...
 - Intel Edison学习笔记(一)——  刷系统
			
一.下载安装包 1.固件安装包:官网下载地址:http://downloadmirror.intel.com/ ... image-ww25.5-15.zip2 2.烧录工具下载地址:http://d ...
 - ROS学习(十三)——  编写简单的Service和Client (C++)
			
一.编写Service节点 1.节点功能: 我们将创建一个简单的service节点("add_two_ints_server"),该节点将接收到两个整形数字,并返回它们的和. 2. ...
 - SpringBoot配置属性之Migration
			
SpringBoot配置属性系列 SpringBoot配置属性之MVC SpringBoot配置属性之Server SpringBoot配置属性之DataSource SpringBoot配置属性之N ...
 - wxss解析
			
一.概述 wxss是样式语言,用于描述wxml组件样式: 在css基础上扩展而来: 1.尺寸单位: rpx, rem 2.支持样式导入 @import语句导入外联样式表 note: 微信小程序一般使 ...
 - elk之elasticsearch 入门
			
一.概述: 1.查看elasticsearch集群的健康状况: [root@node115 kibana]# curl -X GET http://192.168.39.115:9200/_cat/h ...
 - 【Spring】SpringMVC之详解AOP
			
1,AOP简介 Aspect Oriented Programming 面向切面编程.AOP还是以OOP为基础,只不过将共同逻辑封装为组件,然后通过配置的方式将组件动态切入到原有组件中.这样做的有点 ...
 - Linux命令-进程后台执行:nohup(就是不挂起的意思)
			
nohup 就是不挂起的意思( no hang up) 用途:LINUX命令用法,不挂断地运行命令. 语法: nohup Command [ Arg ... ] [ & ] 描述:nohup ...