zoukankan      html  css  js  c++  java
  • 《深入了解Java虚拟机》笔记-jvm 类加载机制

    一、类的初始化

    主动引用:比较常见的场景有

    1、使用new关键字去实例化一个对象,读取或者设置一个类的静态字段(被final修饰的静态常量除外,这样的字段会在编译阶段被放入常量池中,不会触发类的加载),调用一个类的静态方法。

    2、使用java.lang.reflect的方法对类进行反射调用的时候,如果类没有被初始化,则会初始化这个类

    3、当初始化一个子类的时候,如果其父类还没有进行初始化,则要先触发其父类的初始化。

    4、虚拟机启动时会初始化程序的入口类(比如包含main方法的那个类)

    以上的四种情形都是对类的主动引用,会触发类的初始化。

    被动引用:

    1、子类引用父类的静态变量,不会触发子类的初始化。对于一个静态变量,只有直接定义这个字段的类才会被初始化。

    class Parent {
        static {
            System.out.println("parent init!");
        }
        protected static String val = "jvm";
    }
    
    class Child extends Parent{
        static {
            System.out.println("child init");
        }
    }
    
    public class InitDemo{
        public static void main(String[] args) {
            System.out.println(Child.val);
        }
    }
    结果为:
    parent init!
    jvm

    子类没有被初始化

    2、常量在编译阶段会被放入到调用类的常量池中,本质上没有直接引用到定义常量的类,不会触发定义常量的类的初始化

    class Normal{
        public final static String str = "jvm";
        static {
            System.out.println("Normal init");
        }
    }
    
    public class ConstantDemo {
        public static void main(String[] args) {
            System.out.println(Normal.str);
        }
    }
    结果为:
    jvm
    
    Normal 类并没有被初始化

    上面的代码在执行过程中并没有输出Normal init,虽然ConstantDemo 在源码中引用了Normal类的常量str,但是在编译阶段此常量的值"jvm"存储到了ConstantDemo的常量池中,对常量Normal.str的引用转化成ConstantDemo对于自身常量池的引用了,因此不会触发Normal 类的初始化。

  • 相关阅读:
    浅谈一致性Hash原理及应用
    学习sql中的排列组合,在园子里搜着看于是。。。
    SQL Server DAC——专用管理员连接
    通过phantomjs 进行页面截图
    《javascript算法--对象的比较》
    React-生命周期的相关介绍
    常用的谷歌插件
    webpack的externals的使用
    mac 10.12显示隐藏文件
    “文字”聚合、散出动画-转自奇舞团
  • 原文地址:https://www.cnblogs.com/wbringarden/p/9710862.html
Copyright © 2011-2022 走看看