場景
在使用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}
}