JVM 类加载器(3)类的初始化

作者: zidea | 来源:发表于2019-04-09 07:31 被阅读27次
core-java.jpg
public class ZiClientB {
    public static void main(String[] args) {
        System.out.println(MParentB.M_STRING);
    }
}

class MParentB{
    public static final String M_STRING = UUID.randomUUID().toString();

    static {
        System.out.println("mparent static block...");
    }
}
mparent static block...
a2934bf0-dbac-4a26-b334-97ec67c1f126

关键是常量值是否能够在编译器确定下来,当一个常量值并非编译期间确定的,就不会被放置在调用类的常量池中,运行时会主动地使用常量所在类,这样就会初始化这个类。
即使删除 MParentB.class 也不会影响程序运行

public class ZClientC {
    public static void main(String[] args) {
        MParentC mParentC = new MParentC();
    }
}

class MParentC{
    static {
        System.out.println("mparent static block ...");
    }
}

static {} 在类初始化时候会执行,且只会被执行一次,如果使用 {} 会被执行多次,每一次实例化对象都会执行{}括号中的代码。

mparent static block ...
    public static void main(String[] args) {
        MParentC mParentC = new MParentC();
        MParentC mParentCa = new MParentC();
    }
    public static void main(String[] args) {
//        MParentC mParentC = new MParentC();
//        MParentC mParentCa = new MParentC();
        MParentC[] mParentCSs = new MParentC[1];
    }
    public static void main(String[] args) {
//        MParentC mParentC = new MParentC();
//        MParentC mParentCa = new MParentC();
        MParentC[] mParentCSs = new MParentC[1];
        System.out.println(mParentCSs.getClass());
    }

当我们创建一个数组时候,数组类型是由 JVM 在运行时创建,无需加载数组的具体类型,所以不会初始化 MParentC 这个类从而也不会执行 static 的代码,通过 getClass 获取起类型为 [

class [Lcom.zidea.jvm.demo.MParentC;
  MParentC[][] mParentCSss = new MParentC[1][1];
        System.out.println(mParentCSss.getClass());
        System.out.println(mParentCSss.getClass().getSuperclass());
class [Lcom.zidea.jvm.demo.MParentC;
class [[Lcom.zidea.jvm.demo.MParentC;
class java.lang.Object

对于数组实例来说,其类型是由 JVM 在运行时动态生成的,表示为[Lcom.zidea.jvm.demo.MParentC 这种形式。动态生成类型其父类型就是Object,对于数组来说的构成数组的元素为Component 实际上就是将数组降低一个维度的类型。

 int[] employeeIds = new int[1];
        System.out.println(employeeIds.getClass());
        System.out.println(employeeIds.getClass().getSuperclass());
class [I
class java.lang.Object

 public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_1
         1: anewarray     #2                  // class com/zidea/jvm/demo/MParentC
         4: astore_1
         5: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         8: aload_1
         9: invokevirtual #4                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
        12: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
        15: iconst_1
        16: iconst_1
        17: multianewarray #6,  2             // class "[[Lcom/zidea/jvm/demo/MParentC;"
        21: astore_2

助记符
anewarray: 其中 anewarray 表示创建一个引用类型的(如类、接口或数组)数组,并将其引用值压入栈顶。

45: iconst_1
        46: newarray       int
        48: astore_3
        49: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;

助记符
newarray: 其中 newarray 表示创建原始类型(如int、float 或 char)数组,并将其引用值压入栈顶。

之所以没有实例化 mParentC 这是因为只是创建数组的实例,实例类型是 JVM 在运行时创建的。所以这里并没有实例化 mParentC

i263315.jpg

相关文章

  • ClassLoad

    类的加载过程:类的加载—>类的连接—>类的初始化 类加载器ClassLoader JVM 定义了两种类型的类加载器...

  • 类的加载

    jvm中,类的加载分为:加载+链接+初始化在这个过程中,类的加载少不了类加载器。它与反射功能类似。 类加载器分为启...

  • 每天一个知识点(3)--JVM-类加载子系统-类加载器

    JVM的类加载子系统负责加载相关的类,加载类是JVM中类加载器的功能和职责。首先明确下JVM中的类加载器,分为以下...

  • 我的秋招之路-面经篇

    Java基础 类加载的时机和类初始化的时机(引出tomcat类加载器)JVM和绝大多数用户自定义的类在JVM启动的...

  • jvm系列之 类加载器及热加载的简易实现

    1.类加载器: 在上一篇博文中《jvm类加载器机制一》中的7个阶段,加载->验证->准备->解析->初始化->使用...

  • JVM类加载学习三-类加载器

    JVM类加载器 @(Java)[JVM|类加载器] 类加载过程中的加载阶段在JVM的外部实现。这样做可以让应用程序...

  • 类加载

    jvm的类加载,可以分为以下3个步骤 加载 加载,是指jvm借助类加载器查找字节流,并且据此创建类的过程。对于数组...

  • 【深入理解Java虚拟机 】类的加载器

    1. 类加载器的分类 JVM 自带的类加载器 根类加载器( BootStrap ) 拓展类加载器 ( Extens...

  • java类加载机制、类加载器、自定义类加载器

    java类加载机制、类加载器、自定义类加载器 类加载机制 java类从被加载到JVM到卸载出JVM,整个生命周期包...

  • 【1】JVM类加载机制

    目录:1.jvm在什么情况下会加载一个类?2.验证、准备和初始化的过程?3.核心阶段:初始化4.类加载器和双亲委派...

网友评论

    本文标题:JVM 类加载器(3)类的初始化

    本文链接:https://www.haomeiwen.com/subject/poysiqtx.html