Java双大括号_Java“双大括号初始化”的效率?

这里的问题,当我太累了匿名内部类:

2009/05/27 16:35 1,602 DemoApp2$1.class

2009/05/27 16:35 1,976 DemoApp2$10.class

2009/05/27 16:35 1,919 DemoApp2$11.class

2009/05/27 16:35 2,404 DemoApp2$12.class

2009/05/27 16:35 1,197 DemoApp2$13.class

/* snip */

2009/05/27 16:35 1,953 DemoApp2$30.class

2009/05/27 16:35 1,910 DemoApp2$31.class

2009/05/27 16:35 2,007 DemoApp2$32.class

2009/05/27 16:35 926 DemoApp2$33$1$1.class

2009/05/27 16:35 4,104 DemoApp2$33$1.class

2009/05/27 16:35 2,849 DemoApp2$33.class

2009/05/27 16:35 926 DemoApp2$34$1$1.class

2009/05/27 16:35 4,234 DemoApp2$34$1.class

2009/05/27 16:35 2,849 DemoApp2$34.class

/* snip */

2009/05/27 16:35 614 DemoApp2$40.class

2009/05/27 16:35 2,344 DemoApp2$5.class

2009/05/27 16:35 1,551 DemoApp2$6.class

2009/05/27 16:35 1,604 DemoApp2$7.class

2009/05/27 16:35 1,809 DemoApp2$8.class

2009/05/27 16:35 2,022 DemoApp2$9.class

这些都是我在做一个简单的应用程序时生成的,并且使用了大量的匿名内部类 – 每个类将被编译成一个单独的类文件。

如前所述,“双括号初始化”是一个带有实例初始化块的匿名内部类,这意味着为每个“初始化”创建一个新类,所有这些都是为了创建单个对象。

考虑到Java虚拟机在使用它们时需要读取所有这些类,这可能导致bytecode verfication进程等等一段时间。更不用说增加所需的磁盘空间,以便存储所有这些类文件。

看起来好像有一点开销,当使用双括号初始化时,所以它可能不是一个好主意,去太多了它。但是,正如Eddie在评论中指出的,不可能绝对确定影响。

仅供参考,双括号初始化如下:

List list = new ArrayList() {{

add("Hello");

add("World!");

}};

它看起来像Java的一个“隐藏”功能,但它只是一个重写:

List list = new ArrayList() {

// Instance initialization block

{

add("Hello");

add("World!");

}

};

List intList = [1, 2, 3, 4];

Set strSet = {"Apple", "Banana", "Cactus"};

Map truthMap = { "answer" : 42 };

可悲的是,它didn’t make its way既Java 7也不8,并被无限期搁置。

实验

这里是我测试的简单实验 – 使用元素“Hello”和“World!”创建1000个ArrayList。通过add方法添加到它们,使用两种方法:

方法1:双支架初始化

List l = new ArrayList() {{

add("Hello");

add("World!");

}};

方法2:实例化ArrayList并添加

List l = new ArrayList();

l.add("Hello");

l.add("World!");

我创建了一个简单的程序来写出一个Java源文件来执行1000初始化使用两种方法:

测试1:

class Test1 {

public static void main(String[] s) {

long st = System.currentTimeMillis();

List l0 = new ArrayList() {{

add("Hello");

add("World!");

}};

List l1 = new ArrayList() {{

add("Hello");

add("World!");

}};

/* snip */

List l999 = new ArrayList() {{

add("Hello");

add("World!");

}};

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

}

}

测试2:

class Test2 {

public static void main(String[] s) {

long st = System.currentTimeMillis();

List l0 = new ArrayList();

l0.add("Hello");

l0.add("World!");

List l1 = new ArrayList();

l1.add("Hello");

l1.add("World!");

/* snip */

List l999 = new ArrayList();

l999.add("Hello");

l999.add("World!");

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

}

}

请注意,使用System.currentTimeMillis来检查初始化1000个ArrayList的耗用时间和扩展ArrayList的1000个匿名内部类,因此定时器没有非常高的分辨率。在我的Windows系统上,分辨率大约为15-16毫秒。

两次测试的10次运行的结果如下:

Test1 Times (ms) Test2 Times (ms)

---------------- ----------------

187 0

203 0

203 0

188 0

188 0

187 0

203 0

188 0

188 0

203 0

可以看出,双括号初始化具有大约190ms的显着执行时间。

同时,ArrayList初始化执行时间出现为0 ms。当然,应该考虑定时器分辨率,但是它可能在15ms以下。

因此,这两种方法的执行时间似乎有显着的差异。看起来确实有一些开销在两个初始化方法。

是的,有1000个.class文件通过编译Test1双括号初始化测试程序生成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值