先来看一个常见的例子
来看 TestClass,我在 TestClass 中放了 static 代码块以及实例初始化和构造方法:
- package cn.sumile;
- public class TestClass {
- int i = 2;
- {
- System.out.println("实例初始化" + i);
- }
- static {
- System.out.println("静态代码块");
- }
- public TestClass() {
- System.out.println("构造函数" + i);
- }
- public int getI() {
- return i;
- }
- public void setI(int i) {
- this.i = i;
- }
- }
- new TestClass();
- System.out.println("==================");
- new TestClass();
上面是调用的代码,这个是它的调用结果:
- 静态代码块
- 实例初始化 2
- 构造函数 2
- ==================
- 实例初始化 2
- 构造函数 2
从上面我们知道了,在实例化这个类的时候,会首先调用类中的静态代码块(也就是:static{}),然后会开始调用构造块 (也就是:{}),然后才会调用 java 的构造方法。
那么,当我们像下面这样做的时候都发生了什么?
- System.out.println(
- new TestClass() {
- ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: 1 {
- 2 }
- }.getI()
- );
- System.out.println("================");
- new TestClass() {
- {
- i = 3;
- }
- };
上面那个,当我们用反编译工具对生成的.class 文件进行反编译之后我们可以看到:
- class MainClass
- ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: {
- 1()
- {
- setI(3);
- }
- }
可以看到,程序根据 2 之间的代码生成了一个文件,而这个文件的名称是这样的:XXX$1.class。
$后面跟数字是匿名类编译出来的
$后面跟文字是内部类编译出来的
由此我们知道了,MainClass$1 这个 class 文件是一个匿名内部类搞出来的,也就是这个代码搞出来的:
- {
- setI(3);
- }
那实际上在 new TestClass 的时候真正发生的是什么呢?
测试代码下载(包含反编译工具)首先调用 static 代码块,然后调用 block 构造块,然后调用父类的构造方法,然后调用子类(MainClass$1.class)的构造方法,最后才会调用 setI(3)。至此,实例化 TestClass 完成。
扩展
希望看一下这个网页,我觉得挺有用的:Java 中 HashMap 初始化的另一种方式详解
关于这个网页里面说的最后的执行效率问题,我觉得应该是出在了每次都要对匿名内部类搞几个文件,这是之前他测试的代码:
- long st = System.currentTimeMillis();
- /*
- for (int i = 0; i < 10000000; i++) {
- HashMap<String, String> map = new HashMap() {
- {
- put("Name", "June");
- put("QQ", "2572073701");
- }
- };
- }
- System.out.println(System.currentTimeMillis() - st); // 1217
- */
- for (int i = 0; i < 10000000; i++) {
- HashMap<String, String> map = new HashMap();
- map.put("Name", "June");
- map.put("QQ", "2572073701");
- }
- System.out.println(System.currentTimeMillis() - st); // 1064
所以我测试了下面的代码,发现他们所耗费的时间相差无几(实际上一会儿这个占用时间多一会儿那个占用时间多,可能跟电脑有关系,而不是每次都是第二个所耗费的时间比较多)
- HashMap map = new HashMap() {
- {
- for (int i = 0; i < 10000000; i++) {
- put("Name", "June");
- put("QQ", "2572073701");
- }
- }
- };
- System.out.println(System.currentTimeMillis() - st);
- long st2 = System.currentTimeMillis();
- HashMap<String, String> map2 = new HashMap();
- for (int i = 0; i < 10000000; i++) {
- map2.put("Name", "June");
- map2.put("QQ", "2572073701");
- }
- System.out.println(System.currentTimeMillis() - st2);
转载请注明:热爱改变生活.cn » Java 中 statci 与 {} 与构造方法的一种使用技巧
本博客只要没有注明“转”,那么均为原创。 转载请注明链接:sumile.cn » Java 中 statci 与 {} 与构造方法的一种使用技巧