• 类加载机制(二)


    一:接口加载机制

    先看看这个例子
    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缺失或异常时,只有在主动使用该类时才会报告错误

  • 相关阅读:
    ld: library not found for -lstdc++.6
    WebViewJavascriptBridge 进行js 与native通信。
    invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
    OC 与 js 界面JSBridge交互
    react-native init的时候出现问题:npm WARN React-native@0.35.0 requires a peer of react@~15.3.1 but none was
    react-无状态组件
    2018年末--积极拥抱h5.转载 大前端时代来临,我们何去何从?
    /Users/macbook/Library/Developer/Xcode/DerivedData/MapViewDemo: No such file or direc
    EXCEL中如何获得工作表(sheet)的名称
    DELPHI中Showmodal与Show的区别
  • 原文地址:https://www.cnblogs.com/xhlwjy/p/11284984.html
Copyright © 2020-2023  润新知