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 类的初始化。

  • 相关阅读:
    村上春树的《海边的卡夫卡》与中日现实
    熊的甜蜜世界
    VS创建dll和调用dll
    DIRECTSHOW在VS2005中PVOID64问题和配置问题
    Vs 2008 解决方案的目录结构设置和管理
    SQL Server 2008中的代码安全(二):DDL触发器与登录触发器
    如何在自动SGA管理模式下调节参数设置
    将ORACLE数据库从归档改成非归档状态
    查看oracle数据库是否归档和修改归档模式(转)
    oracle TRANSLATE函数详解
  • 原文地址:https://www.cnblogs.com/wbringarden/p/9710862.html
Copyright © 2011-2022 走看看