Java中statci与{}与构造方法的一种使用技巧

无简介

先来看一个常见的例子

来看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() {
$1{
setI(3);
$2}
}.getI()
);
System.out.println(“================”);
new TestClass() {
{
i = 3;
}
};

上面那个,当我们用反编译工具对生成的.class文件进行反编译之后我们可以看到:

class MainClass$1 extends TestClass
{
MainClass$1()
{
setI(3);
}
}

可以看到,程序根据$1-$2之间的代码生成了一个文件,而这个文件的名称是这样的:XXX$1.class。

$后面跟数字是匿名类编译出来的 $后面跟文字是内部类编译出来的

由此我们知道了,MainClass$1这个class文件是一个匿名内部类搞出来的,也就是这个代码搞出来的:

{
setI(3);
}

那实际上在new TestClass 的时候真正发生的是什么呢?

首先调用static代码块,然后调用block构造块,然后调用父类的构造方法,然后调用子类(MainClass$1.class)的构造方法,最后才会调用setI(3)。至此,实例化TestClass完成。

[dl href=‘http://pan.baidu.com/s/1hq8Ov7u’]测试代码下载(包含反编译工具)[/dl]

扩展

希望看一下这个网页,我觉得挺有用的: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);

-------------本文结束  感谢您的阅读-------------
下次一定