背景
最近在使用HashSet
的时候, 为了方便初始化操作,看到了网上一些文章,使用java匿名内部类
的方式进行初始化.
HashSet<String> hashSet = new HashSet<String>(){{
add("xxx1");
add("xxx2");
add("xxx3");
}};
上面这段代码, 是使用匿名内部类 + 构造代码块 的方式进行初始化. 改写一下:
HashSet<String> hashSet = new HashSet<String>(){
{
add("xxx1");
add("xxx2");
add("xxx3");
}
};
构造代码块的作用
- 构造代码块的作用是给对象进行初始化。
- 对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。
- 构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
Class
使用匿名内部类初始化HashSet
后, 编译java文件, 发现新增了一个class
文件
package com.example.demo.innerclass;
import java.util.HashSet;
public class Test {
public static void main(String[] args) throws Exception {
HashSet<String> hashSet = new HashSet<String>() {{
add("xxx1");
add("xxx2");
}};
}
}
在目录下执行命令: javac Test.java
发现目录下多了一个文件: Test$1.class
使用IDEA
打开:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.example.demo.innerclass;
import java.util.HashSet;
final class Test$1 extends HashSet<String> {
Test$1() {
this.add("xxx1");
this.add("xxx2");
}
}
匿名内部类是继承了一个类后,生成的子类.