静态内部类加载顺序

咱们先来区分一下两个概念:类加载、加载。java

类加载的过程包括加载,初始化,验证,解析,准备,初始化等五个过程。加载是类加载的一部分。面试

区分完这两个概念以后咱们再来看下面的问题。app

咱们声明一个类,这个类有个内部静态类。还有主函数,当咱们启动程序以后,运行java application程序。函数

运行结果是什么呢?.net

下面看个代码实现的例子:对象

package Test;

public class OuterClass {
static {
System.out.println("加载外部类");
}
static class InnerClass{
public InnerClass() {}
static {
System.out.println("加载内部类");
}
static void innerMethod() {
System.out.println("内部类的静态方法");
}
static int a;
}

public static void main(String[] args) {
OuterClass out=new OuterClass();
System.out.println("=============");
// OuterClass.InnerClass.a=1;
}

}
 blog

 

外部类的静态代码块执行了。内部类的静态代码块没有执行在外部类执行静态代码块以后执行,是由于内部类没有加载么?内存

其实不是这样的,一旦程序运行,全部该类涉及的类(包括内部类和从其余包导入的类)都会在类加载的过程当中加载到get

内存,由于在整个程序运行的过程当中类加载只会发生一次,一旦某个类没有被加载,那么将不能再使用这个类。博客

注意我标出来的加载,这里是指在类加载过程当中的加载,可是咱们能够在网上了解或者在书上得知,只有当某个类

初始化以后,才会调用类的静态代码块。才会执行对应的。那么何时执行类加载过程当中的类初始化呢?

只有当咱们有对类的引用的时候,才会将类初始化。

好比咱们new一个非静态类的对象,或者对某个静态类的成员(包括成员方法和域)或者调用有访问的时候

若是咱们把最后一行的注释去掉,就会执行内部静态类的静态代码块(static{})。

 

或者有隐式的调用咱们类的方法。为何咱们的外部类没有new的时候还会执行他的静态代码块呢?

是否是忘了还有个主函数在执行,这时候是调用了类的方法的,因此会初始化这个外部类。执行外部类的静态代码块。

关于静态代码块,代码块,类的构造函数执行顺序问题不态理解的同窗能够看看个人博客:

Java面试题 类的构造函数的执行顺序问题

注意:内部静态类不会自动初始化,只有调用静态内部类的方法,静态域,或者构造方法的时候才会加载静态内部类。

利用这种特色咱们能够实现一个单例模式

package Test;

public class Single {

private Single() {}

static class SingleHolder {

private static final Single instance=new Single();

}
public static Single getinstance() {
return SingleHolder.instance;
}

public static void main(String[] args) {

Single a=Single.getinstance();
Single b=Single.getinstance();
Single c=Single.getinstance();
System.out.println(a.toString());
System.out.println(b.toString());
System.out.println(c.toString());
}

}
上面程序的运行结果:

 

当咱们用的构造方法声明为private的时候,表明这个类只能被本身调用,就算同包下的类也不能实例化。

这并非构造函数只会被调用一次,而且保证只会实例化一次类的缘由。若是你把上面的构造函数变成public,

也是只生成一个对象。

相关文章
相关标签/搜索