类加载机制(二)

一:接口加载机制

先看看这个例子
public class Test1 {
    public static void main(String[] args) {
        System.out.println(MyChild15.b);
    }
}
interface MyInterface5{
    public static int a=5;
}
interface MyChild15 extends MyInterface5{
    public static int b=10;
}

console:

10
View Code

这个呢?

此处将编译后的.class删掉

public class Test1 {
    public static void main(String[] args) {
        System.out.println(MyChild15.b);
    }
}
interface MyInterface5{
    public static int a=5;
}
interface MyChild15 extends MyInterface5{
    public static int b=10;
}

Console:

NoClassDeFoundError

总结:当一个接口初始化时,并不要求初始化父接口初始化,只有正真使用到父接口的时候才会初始化

 

下面再看一个例子

public class Test1 {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        System.out.println(singleton.counter1);
        System.out.println(singleton.counter2);
    }
}

class Singleton{
    public static int counter1;
    public static int counter2=0;
    private static Singleton singleton=new Singleton();
    private Singleton(){
        counter1++;
        counter2++;
    }
    public static Singleton getInstance(){
        return singleton;
    }
}

console:

1
1
View Code

相信这个大家都能想到,先调用得到实例的方法,然后初始化

再看看下面这个程序

public class Test1 {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        System.out.println(singleton.counter1);
        System.out.println(singleton.counter2);
    }
}

class Singleton{
    public static int counter1;
    private static Singleton singleton=new Singleton();
    private Singleton(){
        counter1++;
        counter2++;//准备阶段的重要意义
    }
    public static int counter2=0;
    public static Singleton getInstance(){
        return singleton;
    }
}

console:

1
0
View Code

这是为什么呢?

因为类加载分为3个阶段,在第3个阶段初始化先为所有变量赋上初值counter1,counter20singletonnull,然后再第三阶段赋值,顺序执行counter2++1,然后又被设置为0

再来完整整理一遍类加载的步骤

  1. 加载:将二进制文件读入java虚拟机
  2. 验证:

    准备:为类分配内存,设置默认值

    解析:在类型的常量池中寻找类,接口,字段,方法的符号引用,把符号引用变成直接引用

   3.初始化:为类赋予正确的初始值

 

二:类的加载器

类的加载的最终产品是位于内存当中的Class对象

2种类型的类加载器

  1. JVM自带的类加载器
    1. 根类加载器(bootstrap
    2. 扩展类加载器(extension
    3. 系统类加载器(SyStem)
  2. 用户自定义类加载器

    Java.lang.ClassLoader的子类

    自己定制类的加载器

注:类加载器并不需要等到某个类被首次主动使用时再加载它,如果存在.class缺失或异常时,只有在主动使用该类时才会报告错误

 

posted @ 2019-08-01 20:06  沦为旧友  阅读(124)  评论(0编辑  收藏  举报