Java中双大括号初始化的理解与使用

网友投稿 280 2022-07-22


目录对该方法的理解效率问题总结

偶然机会看到一种对象初始的方式:

// 新建一个列表,并赋值 "Harry","Tony","Tom"

ArrayList friends = new ArrayList() {{

add("Harry");

add("Tony");

add("Tom");

}};

当然,对Map集合也用同种初始化方式:

// 新建一个Map,并赋值

Map cat = new HashMap() {{

put("name", "Tom");

put("age", 10);

}};

这里利用了内部类语法,这种方式比先new出对象然后再进行依次add要方便、简洁许多。该方法称之为“双括号初始化”(double brace initialization)。

对该方法的理解

以ArrayList的初始化为例,第一层花括号,首先对定义了一个继承自ArrayList的匿名内部类

ArrayList friends = new ArrayList() {

// 这里什么操作都没有,全部继承自父类(ArrayList)

};

第二层则是一个自定义的对象构造块(称之为 非静态初始化块)

new ArrayList() {

// 这里什么操作都没有,全部继承自父类(ArrayList)

};

我们通过new得到ArrayList的子类的实例化,然后上转型为ArrayList的引用

ArrayList friends = new ArrayList() {{}};

我们得到的 friends 实际上是ArrayList的子类的引用,但在功能上没有任何改变相比于常规标准方式进行初始化要简洁许多(但代码可读性相对会差)

效率问题

利用双大括号初始化集合从效率上来说可能不如标准的集合初始化步骤。原因在于使用双大括号初始化会导致内部类文件的产生,而这个过程就会影响代码的执行效率。

首先查看不同初始化方式生成的.class文件

例如以下代码:

public class Test1 {

public static void main(String[] args) {

System.out.println(System.currentTimeMillis());

ArrayList list1 = new ArrayList() {{

add("Harry");

add("Tony");

add("Tom");

add("Jerry");

}};

ArrayList list2 = new ArrayList() {{

add("Harry");

add("Tony");

add("Tom");

add("Jerry");

}};

ArrayList list3 = new ArrayList() {{

add("Harry");

add("Tony");

add("Tom");

add("Jerry");

}};

ArrayList list4 = new ArrayList() {{

add("Harry");

add("Tony");

add("Tom");

add("Jerry");

}};

ArrayList list5 = new ArrayList() {{

add("Harry");

add("Tony");

add("Tom");

add("Jerry");

}};

……

…snip…

……

ArrayList list1000 = new ArrayList() {{

add("Harry");

add("Tony");

add("Tom");

add("Jerry");

}};

System.out.println(System.currentTimeMillis());

}

}

Test1编译后生成http://的.class列表为:

Test1$1.classTest1$2.classTest1$3.classTest1$4.classTest1$5.class………snip………Test1$1000.classTest1.class

生成了 1001个.claDjmIogqss文件

public class Test2 {

public static void main(String[] args) {

System.out.println(System.currentTimeMillis());

ArrayList list1 = new ArrayList<>();

list1.add("Harry");

list1.add("Tony");

list1.add("Tom");

list1.add("Jerry");

ArrayList list2 = new ArrayList<>();

list2.add("Harry");

list2.add("Tony");

list2.add("Tom");

list2.add("Jerry");

ArrayList list3 = new ArrayList<>();

list3.add("Harry");

list3.add("Tony");

list3.add("Tom");

list3.add("Jerry");

ArrayList list4 = new ArrayList<>();

list4.add("Harry");

list4.add("Tony");

list4.add("Tom");

list4.add("Jerry");

ArrayList list5 = new ArrayList<>();

list5.add("Harry");

list5.add("Tony");

list5.add("Tom");

list5.add("Jerry");

……

…snip…

……

ArrayList list1000 = new ArrayList<>();

list1000.add("Harry");

list1000.add("Tony");

list1000.add("Tom");

list1000.add("Jerry");

System.out.println(System.currentTimeMillis());

}

}

Test2编译后生成的.class列表为:

Test2.class

只生成了1个.class文件

运行时间

第一段代码Test1运行结果:

15083794522241508379452784

运行时间为:560毫秒

第二段代码Test2运行结果:

15083796715051508379671507

运行时间为:2毫秒

虽然说这个时间差距会根据电脑性能以及运行状态有所变化,但也能说明双大括号初始化方法要比常规方法用时长

综上,(测试初始化数据较少(list未达到自增临界点)的情况下)双大括号初始化方法要比常规方法效率低:

1. 双大括号初始化方法生成的.class文件要比常规方法多

2. 双大括号初始化方法运行时间要比常规方法长

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Jackson多态序列化图文详解
下一篇:Java多线程Thread类的使用及注意事项
相关文章

 发表评论

暂时没有评论,来抢沙发吧~