场景
在使用pol-tl操作word的时候,初始化Map的时候使用了如下代码
在上面的初始化方式中,使用到了两个大括号{{}}
看似有些陌生的语法,实际上这是匿名内部类和实例化代码块的结合
实例化代码块
先看一道面试题:
class Person {
{
System.out.println("初始化代码块");
}
public Person(String name, Integer age, Integer id) {
this.name = name;
this.age = age;
this.id = id;
System.out.println("执行构造函数");
}
private String name;
private Integer age;
private Integer id;
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public Integer getId() {
return id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
public static void main(String[] args) {
Person p = new Person("张三", 18, 1);
System.out.println(p);
// 初始化代码块
// 执行构造函数
// Person{name='张三', age=18, id=1}
}
}
上面的输出结果很好解释,因为初始化代码块在创建实例的时候执行,并且在构造函数内执行
匿名内部类
匿名内部类可以是一个接口的实现。
interface Flyable {
void fly();
}
public class Application {
public static void main(String[] args) {
Flyable f = new Flyable() {
@Override
public void fly() {
System.out.println("我在飞");
}
};
f.fly();
}
}
匿名内部类也可以是对一个类的扩展。
class Animal {
private String name;
public void say() {
System.out.println("hello, kangkang");
}
}
public class Application {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Animal a = new Animal() {
public void fly() {
System.out.println("我在飞");
}
};
Method method = a.getClass().getMethod("fly");
method.invoke(a,null); // 我在飞
}
}
上面的代码就相当于一个自定义了一个类继承了Animal类,并且在Animal类的基础上扩充了fly方法。因为引用是Animal类型,所以不能直接调用fly方法。但是通过反射可以调用fly方法,说明fly是确实存在的。
根据这个原理,我们可以直接在匿名内部类里面写代码块
class Animal {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
'}';
}
}
public class Application {
public static void main(String[] args) {
Animal a = new Animal() {
{
setName("Lisa");
}
};
System.out.println(a); // Animal{name='Lisa'}
}
}
main函数里的代码相当于下面代码:
public static void main(String[] args) {
class Child extends Animal {
{
setName("Lisa");
}
}
Animal a = new Child();
System.out.println(a); // Animal{name='Lisa'}
}
所以我们在创建对象的时候可以使用{{}}
来初始化对象,比如HashMap:
public static void main(String[] args) {
System.out.println(new HashMap<String, Object>() {{
put("k1", "v1");
put("k2", "v2");
}});
// {k1=v1, k2=v2}
}