iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java类的加载时机
  • 470
分享到

Java类的加载时机

2024-04-02 19:04:59 470人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

必须初始化的四种情况 有四种情况类是必须要进行初始化的,对于这四种情况原文描述如下: 但是对于初始化阶段,虚拟机规范则是严格规定了有且只有4种情况必须立即对类进行初始化,而加载、验证

必须初始化的四种情况

有四种情况类是必须要进行初始化的,对于这四种情况原文描述如下:

但是对于初始化阶段,虚拟机规范则是严格规定了有且只有4种情况必须立即对类进行初始化,而加载、验证、准备自然需要在此之前开始。

  • 1:遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令最常见的java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
  • 2:使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
  • 3:当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
  • 4:当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

以上四点我们一一用代码来验证,第一点里面说到了四种初始化的场景,分别是:

  • ①用new关键字实例化对象
  • ②读取类静态字段
  • ③设置类的静态字段
  • ④调用一个类的静态方法

在验证之前需要达成一个共识:虚拟机在初始化类时会执行static语句块中的操作,因此我们可以根据静态语句块中的代码是否执行了来判断类是否加载。为此我创建了一个SubClass类


package com.test.JVM.classloading;


public class SubClass {
    static{
        System.out.println("子类初始化");
    }
    public static int a = 10;

    public static int getA(){
        return a;
    }
}

在main方法中分别执行(每次执行一条)以下四条代码来模拟上面四个场景


package com.test.jvm.classloading;


public class Main {
    public static void main(String[] args) {
        SubClass subClass = new SubClass();
        System.out.println(SubClass.a);
        SubClass.getA();
        SubClass.a = 30;
    }
}

结果不出所料,输出结果都包含"子类初始化",说明以上四种方式确实可以会触发类的初始化。

接下来看第二点,对类进行反射调用时会触发类的初始化


package com.test.jvm.classloading;


public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("com.test.jvm.classloading.SubClass");
    }
}

以上的反射调用同样正常输出了"子类初始化"。

第三点如果父类没有进行初始化,则要先触发父类的初始化,再创建一个父类,并且让之前的子类继承父类


package com.test.jvm.classloading;


public class SuperClass {
    static {
        System.out.println("父类初始化");
    }
    public static int b = 20;
}

package com.test.jvm.classloading;


public class SubClass extends SuperClass {
    static{
        System.out.println("子类初始化");
    }
    public static int a = 10;

    public static int getA(){
        return a;
    }
}

这时我们再次执行上面的main方法里面的任意一条测试语句,这时发现在原来的输出"子类初始化"前输出了"父类初始化",说明了两点:①父类同样会初始化;②父类会先于子类初始化。

第四点虚拟机会先初始化包含main方法的主类,这时我们在主类中加入静态代码块


package com.test.jvm.classloading;


public class Main {
    static {
        System.out.println("初始化主类");
    }
    public static void main(String[] args) throws ClassNotFoundException {
        SubClass subClass = new SubClass();
    }
}

可以看到输出结果如下,完全印证了第四点。

不主动进行初始化

而对于不会主动进行初始化的情况在该书中也有以下几种情况

第一种是通过子类类名调用父类静态代码(包括静态方法和静态变量)不会进行初始化,以下也通过代码进行说明


package com.test.jvm.classloading;


public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println(SubClass.b);
    }
}

输出如下,可以看到只初始化了父类而没有初始化子类。

第二种是通过数组来创建对象不会触发此类的初始化


package com.test.jvm.classloading;


public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        SuperClass[] supers = new SuperClass[10];
    }
}

输出为空。

第三种是调用final修饰的常量不会触发类的初始化,为此我在父类中加了一个常量


package com.test.jvm.classloading;


public class SuperClass {
    static {
        System.out.println("父类初始化");
    }
    public static int b = 20;

    public final static String STATE = "常量";
}

package com.test.jvm.classloading;


public class Main {
    public static void main(String[] args) {
        System.out.println(SuperClass.STATE);
    }
}

可以看到输出结果只是打印了常量的值,并没有初始化这个类。

补充

到这里对于书中描述的类的加载时机都已经用例子说明了,接下来展示一个在博主Boblim那看到的一个例子



class SingleTon {
    private static SingleTon singleTon = new SingleTon();
    public static int count1;
    public static int count2 = 0;

    private SingleTon() {
        count1++;
        count2++;
    }

    public static SingleTon getInstance() {
        return singleTon;
    }
}

public class Test {
    public static void main(String[] args) {
        SingleTon.getInstance();
        System.out.println("count1=" + SingleTon.count1);
        System.out.println("count2=" + SingleTon.count2);
    }
}

输出count1=1,count2=0,关于为什么会输出这个结果在那篇链接的博客已经做了详细的说明,同时这个输出结果也很好地佐证了下面这句话

类构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的。

正是给类变量赋值时是按照顺序进行的,所以上面count2又会被重新赋值为0,才导致这个输出结果。

以上所述是小编给大家介绍的Java类的加载时机,希望对大家有所帮助。在此也非常感谢大家对编程网网站的支持!

--结束END--

本文标题: Java类的加载时机

本文链接: https://www.lsjlt.com/news/159726.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java类的加载时机
    必须初始化的四种情况 有四种情况类是必须要进行初始化的,对于这四种情况原文描述如下: 但是对于初始化阶段,虚拟机规范则是严格规定了有且只有4种情况必须立即对类进行初始化,而加载、验证...
    99+
    2024-04-02
  • Java类的加载时机与过程
    目录1 开门见山2 类的加载时机3 何时开始类的初始化4 被动引用例子5 类的加载过程5.1 加载5.2验证5.3准备5.4 解析5.5 初始化6 题目分析1 开门见山 以前曾经看到...
    99+
    2024-04-02
  • Java类的加载时机是什么时候
    本篇内容主要讲解“Java类的加载时机是什么时候”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java类的加载时机是什么时候”吧!必须初始化的四种情况有四种情况类是必须要进行初始化的,对于这四种...
    99+
    2023-06-25
  • Java类的加载时机与过程是什么
    本篇内容主要讲解“Java类的加载时机与过程是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java类的加载时机与过程是什么”吧!1 开门见山以前曾经看到过一个java的面试题,当时觉得此题...
    99+
    2023-06-25
  • Java虚拟机之类加载
    目录一、类加载流程1.1 类加载条件1.2 加载1.3 验证1.4 准备1.5 解析1.6 初始化二、ClassLoader2.1 Class...
    99+
    2024-04-02
  • Java类的加载机制是什么
    这篇文章主要讲解了“Java类的加载机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java类的加载机制是什么”吧!1、什么是类的加载类的加载指的是将类的.class文件中的二进制数...
    99+
    2023-06-17
  • 概述java虚拟机中类的加载器及类加载过程
    目录1. 类加载子系统 1.1 概述1.2 类的加载器2.类的加载过程2.1 类的加载过程简图2.2 加载阶段:Loading2.3 链接阶段:Linking2.4 初始化...
    99+
    2024-04-02
  • Java JVM类加载机制解读
    目录1.什么是类加载2.类加载的过程2.1加载2.2验证2.3准备2.4解析2.5初始化【重中之重之重中重】第一段代码:第二段代码:第三段代码:最后一段代码:总结1.什么是类加载 首...
    99+
    2024-04-02
  • 聊一聊Java的JVM类加载机制
    目录加载(Loading)连接(Linking)初始化(Initialization)类初始化的时机总结Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换...
    99+
    2023-05-16
    Java JVM JVM类加载机制
  • Java 类加载机制详细介绍
    一、类加载器  类加载器(ClassLoader),顾名思义,即加载类的东西。在我们使用一个类之前,JVM需要先将该类的字节码文件(.class文件)从磁盘、网络或其他来源加载到内存中,并对字节码进行解析生成对应的Class对象,这就是类加...
    99+
    2023-05-31
    java 加载机制
  • Java中类加载机制的实例讲解
    这篇文章主要介绍“Java中类加载机制的实例讲解”,在日常操作中,相信很多人在Java中类加载机制的实例讲解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中类加载机制的实例讲解”的疑惑有所帮助!接下来...
    99+
    2023-06-20
  • 深入探究Java中的类加载机制
    目录前言步入正题类的加载过程:1.加载2.验证3.准备4.解析5.初始化类加载器源码总结前言 学生时代应抱着问题去学习一门语言,例如:在学习java语言的过程中,我遇到过java主方...
    99+
    2024-04-02
  • 一文详解Java中的类加载机制
    目录一、前言二、类加载的时机2.1 类加载过程2.2 什么时候类初始化2.3 被动引用不会初始化三、类加载的过程3.1 加载3.2 验证3.3 准备3.4 解析3.5 初始化四、父类...
    99+
    2024-04-02
  • jvm类加载器,类加载机制是什么
    这篇文章主要介绍“jvm类加载器,类加载机制是什么”,在日常操作中,相信很多人在jvm类加载器,类加载机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jvm类加载器,类加载机制是什么”的疑惑有所帮助!...
    99+
    2023-06-16
  • Java之类加载机制案例讲解
    1.类加载 <1>.父子类执行的顺序 1.父类的静态变量和静态代码块(书写顺序) 2.子类的静态变量和静态代码块(书写顺序) 3.父类的实例代码块(书写顺序) 4.父类...
    99+
    2024-04-02
  • Java类加载机制有哪些内容
    这篇文章主要介绍“Java类加载机制有哪些内容”,在日常操作中,相信很多人在Java类加载机制有哪些内容问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java类加载机制有哪些内容”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-02
  • 【Java系列】Java虚拟机—类加载器介绍
    什么是Java虚拟机  Java虚拟机(Java Virtual Machine,JVM)是一个能够执行 Java 字节码的虚拟计算机。它是 Java 技术的核心部分,是 Java 应用程序运行的基础。 Java 程序在编译后会...
    99+
    2023-09-01
    java 开发语言 原力计划
  • Java中类的加载器及其加载过程
    目录Java中类的加载器及其加载过程概述过程一:Loading过程二:Linking过程三:InitializationJava中类的加载器及其加载过程 概述 字节码文件在类加载器子...
    99+
    2023-05-16
    Java类的加载器 Java类加载过程 加载器加载过程
  • Java虚拟机之类加载的示例分析
    小编给大家分享一下Java虚拟机之类加载的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序...
    99+
    2023-06-15
  • Java虚拟机JVM类加载机制(从类文件到虚拟机)
    目录一、类加载机制简介二、类加载机制过程 2.1、加载(Load)2.2、连接(Linking)2.3、初始化(Initialize)三、类加载器Classloader&n...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作