Java:双括号初始化 /匿名内部类初始化法
偶然见到一种初始化方式,感到十分新奇:
//新建一个列表并赋初值A、B、C
ArrayList<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
还有其他集合比如HashMap的初始化:
Map map = new HashMap() {{
put("Name", "Unmi");
put("QQ", "1125535");
}};
这种方式比起先new出对象,再一条条add,显得更加简洁和优雅。一开始没想通什么原理,后来查了一下才知道这种方法被称为双大括号初始化(double brace initialization)或者匿名内部类初始化法,实际上是一种取巧的方式。
理解:
这里以ArrayList的例子解释,首先第一层花括号定义了一个继承于ArrayList的匿名内部类 (Anonymous Inner Class):
//定义了一个继承于ArrayList的类,它没有名字
new ArrayList<String>(){
//在这里对这个类进行具体定义
};
第二层花括号实际上是这个匿名内部类实例初始化块 (Instance Initializer Block)(或称为非静态初始化块):
new ArrayList<String>(){
{
//这里是实例初始化块,可以直接调用父类的非私有方法或访问非私有成员
}
};
我们通过new得到这个ArrayList的子类的实例并向上转型为ArrayList的引用:
ArrayList<String> list = new ArrayList<String>() {{}};
- 我们得到的实际上是一个ArrayList的子类的引用,虽然这个子类相比ArrayList并没有任何功能上的改变。
- 可以认为这是个本身装有数据的子类(因为它的数据来自于自身的初始化),而不是取得引用后再赋值。
下面自定义一个类并使用这种方式初始化:
class Person{
protected String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
...
public static void main(String[] args) {
Person p = new Person(){
{
name = "xiaoming"; //或者调用setName()
age = 3; //或者setAge()
}
};
System.out.println(p.getName() + p.getAge());
}
注意:
(1)这种方法一定程度上使代码更简洁,但同时可能降低可读性;还可能会造成内存泄露,在序列化时可能也会出现一些问题(未测试)。
(2)当我们想构造一个数组列表,并将它传递到一个方法时,最初的写法如下:
ArrayList<String> friends=new ArrayList<>();
friends.add("tom");
friends.add("lin");
invite(friends);
如果不想要写这个数组列表,可将其作为一个匿名列表,通过双括号的方式为列表添加元素,这样代码更为简洁。
invite(new ArrayList<String> ()
{
{
add("tom");
add("lin");
}
})
外层“{}”创建了ArrayLIst的一个匿名子类,内层“{}”创建了一个对象构造块。
Java:双括号初始化 /匿名内部类初始化法的更多相关文章
- Java map双括号初始化方式的问题
关于Java双括号的初始化凡是确实很方便,特别是在常量文件中,无可替代.如下所示: Map map = new HashMap() { { put("Name", "Un ...
- Java技巧之双括弧初始化
由于Java语言的集合框架中(collections, 如list, map, set等)没有提供任何简便的语法结构,这使得在建立常量集合时的工作非常繁索.每次建立时我们都要做: 定义一个临时的集合类 ...
- ng1中 如何用双向绑定 实现单向绑定的初始时不显示双括号效果?
ng1中 如何用双向绑定 实现单向绑定(ng-bind就可以不显示{{}})的初始时不显示双括号效果? AngularJS 实例 页面加载时防止应用闪烁: <div ng-app="& ...
- Java 中 HashMap 初始化时赋值
1.HashMap 初始化的文艺写法 HashMap 是一种常用的数据结构,一般用来做数据字典或者 Hash 查找的容器.普通青年一般会这么初始化:HashMap<String, Strin ...
- java在hashmap初始化时赋初值
Java中的HashMap是一种常用的数据结构,一般用来做数据字典或者Hash查找的容器. 一般我们初始化并赋初值是这样做的: HashMap<String, Object> map = ...
- 永远不要使用双花括号初始化实例,否则就会OOM!
生活中的尴尬无处不在,有时候你只是想简单的装一把,但某些"老同志"总是在不经意之间,给你无情的一脚,踹得你简直无法呼吸. 但谁让咱年轻呢?吃亏要趁早,前路会更好. 喝了这口温热的鸡 ...
- Java类的初始化与实例对象的初始化
Java对象初始化详解 2013/04/10 · 开发 · 1 评论· java 分享到:43 与<YII框架>不得不说的故事—扩展篇 sass进阶篇 Spring事务管理 Android ...
- Java面向对象之初始化块
目录 Java面向对象之初始化块 普通初始化块 静态初始化块 初始化块与构造器 Java面向对象之初始化块 在程序设计中,让数据域正确地执行初始化一直是一个亘古不变的真理. 那么,有哪些手段可以初始化 ...
- java基础之:匿名内部类
在java提高篇-----详解内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以 了解到匿名内部类的使用.匿名内部类要注意的事项.如何初 ...
随机推荐
- SQL之运算符操作
算数运算符: 用select可以实现加减乘除,求模操作等: 加法操作, 减法操作, 乘法操作, 除法操作, DIV 除法操作, 求模操作, ...
- UML类图及依赖,泛化,关联,聚合,组合,实现
UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中, ...
- 齐博cms 7.0 漏洞分析
** 0x01 原理分析 ** 还是很早之前爆出来的漏洞,现在拿出来学习一下,参考阿里巴巴: https://security.alibaba.com/... 漏洞发生在/inc/common.inc ...
- win7(iis7)localhost可以访问127.0.0.1不可以访问的问题解决办法
在C:\Windows\System32\drivers\etc文件夹下有hosts文件,用编辑器打开,看看有没有配置127.0.0.1 localhost 把前面的#去掉保存即可!
- Go语言结构体(struct)
Go 语言结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型. 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合. 结构体表示一项记录,比如保存图 ...
- 归并排序(Java)
选择排序的升级版本归并排序, 归并排序有二路归并,三路归并和多路归并,我这次只分析下二路归并,有机会在分析下别的. 归并排序的思想是这样的: 设数组a中存放了n个数据元素,初始时我们把它们看成是n个长 ...
- 迈向angularjs2系列(8):angular cli和angular2种子项目
文章目录 1.angular cli快速搭建项目 2.angular2-seed 3.手动配置 题外话:如何更好的阅读本篇文章 一: angular cli的安装 Angular-cli(命令行界面, ...
- java private修饰的类和变量
private主要用来修饰变量和方法,一般不会用来修饰类,除非是内部类. 1.new对象 被private修饰的变量和方法,只能在自己对象内部使用,其他对象即使是new你这个对象也是获取不到被priv ...
- Android studio一些常见技巧(不断更新)
一.Android studio取消默认每次打开时打开最后一个项目 二.as添加jar包 新建一个libs目录,在java下 进行手动gragle同步或者如下图 三.代码边上的小图标 1.布局文件中存 ...
- httpd2.4常用配置
author:JevonWei 版权声明:原创作品 httpd 2.4配置 切换使用的MPM Centos7:/etc/httpd/conf.modules.d/00-mpm.conf 启用要启用的M ...