前言
最近在看多线程,讲到单例模式安全问题的时候。提到了单例的第四种模式——InnerClass模式。里面提到这种是用的最多的方式。很好奇里面的写法,然后就对静态内部类加载产生了疑问。故写了以下的代码实验一下。
代码1
我们利用静态代码块随着类的加载而执行这一特征,对静态内部类进行了测试。
public class StaticClassTest {
static {
System.out.println("this is static outter calss");
}
public static class Innclass {
static {
System.out.println("this is static inner class");
}
}
public static void main(String[] args) {
new StaticClassTest();//修改在这里
System.out.println("------------我是华丽的分割线-----------");
new StaticClassTest.Innclass();
}
}
```
这段代码的运行结果是
this is static outter calss
------------我是华丽的分割线-----------
this is static inner class
```
这里面看到先是外部类加载,然后在调用内部类创建对象的时候,才会去加载静态内部类。这点和静态成员随着类一起加载有出入。而后,我对代码进行一些修改。
代码2
public class OutterClassTest {
public static void main(String[] args) {
new Outter();//修改在这里
System.out.println("-------我是华丽的分割线--------");
new Outter.Inner();
}
}
class Outter {
static {
System.out.println("this is outter class loading ");
}
public static class Inner {
static {
System.out.println("this is inner calss loading ");
}
}
}
这段代码我将静态类的外部类和测试类分开。执行主方法后,得到如下结果:
this is outter class loading
-------我是华丽的分割线--------
this is inner calss loading
这和上面一段代码没什么区别。但是,当我们将调用外部类的方法创建对象这句话分别注释掉的时候。其结果就发生了变化:
代码1
this is static outter calss
------------我是华丽的分割线-----------
this is static inner class
```
代码2
-------我是华丽的分割线--------
this is inner calss loading
##总结
很明显在这里面,代码1由于是main函数所在的类,必须加载。所以,静态代码块先执行。没什么问题。但主要问题在代码2上,为什么直接调用静态内部类创建对象的时候,外部类都没有加载。
这说明,静态内部类作为一种特殊的类成员有如下两个特征:
1. 加载时间随着调用而加载。而不是和外部类一起加载。
2. 静态内部类作为一个类,是可以单独使用,而不需要加载任何外部类代码的。
以上是我对静态内部类特性的一些总结,如有错误,欢迎指正。谢谢