java中使用雙大號初始化

場景

在使用pol-tl操作word的時候,初始化Map的時候使用瞭如下代碼

初始化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}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章