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}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值