我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java类的加载时机是什么时候

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java类的加载时机是什么时候

本篇内容主要讲解“Java类的加载时机是什么时候”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java类的加载时机是什么时候”吧!

必须初始化的四种情况

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

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

  • 遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令最常见的java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。

  • 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。

  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

  • 当虚拟机启动时,用户需要指定一个要执行的主类(包含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();    }}

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

Java类的加载时机是什么时候

不主动进行初始化

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

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

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

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

Java类的加载时机是什么时候

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

package com.test.jvm.classloading;public class Main {    public static void main(String[] args) throws ClassNotFoundException {        SuperClass[] supers = new SuperClass[10];    }}

输出为空。

Java类的加载时机是什么时候

第三种是调用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);    }}

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

Java类的加载时机是什么时候

补充

到这里对于书中描述的类的加载时机都已经用例子说明了,接下来展示一个在博主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类的加载时机是什么时候”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java类的加载时机是什么时候

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

下载Word文档

猜你喜欢

Java类的加载时机是什么时候

本篇内容主要讲解“Java类的加载时机是什么时候”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java类的加载时机是什么时候”吧!必须初始化的四种情况有四种情况类是必须要进行初始化的,对于这四种
2023-06-25

java类在什么时候加载

类什么时候加载类的加载是通过类加载器(Classloader)完成的,它既可以是饿汉式[eagerly load](只要有其它类引用了它就加载)加载类,也可以是懒加载[lazy load](等到类初始化发生的时候才加载)。 (推荐学习:java
java类在什么时候加载
2016-03-31

Java类的加载时机与过程是什么

本篇内容主要讲解“Java类的加载时机与过程是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java类的加载时机与过程是什么”吧!1 开门见山以前曾经看到过一个java的面试题,当时觉得此题
2023-06-25

Java 类加载机制究竟是什么?(Java类加载机制是什么)

在Java编程中,类加载机制是一个非常重要的概念,它对于Java程序的运行和性能有着深远的影响。本文将详细介绍Java类加载机制的工作原理、过程以及相关的重要概念。一、类加载机制的概述类加载机制是Java虚拟机(
Java 类加载机制究竟是什么?(Java类加载机制是什么)
Java2024-12-22

Java类的加载机制是什么

这篇文章主要讲解了“Java类的加载机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java类的加载机制是什么”吧!1、什么是类的加载类的加载指的是将类的.class文件中的二进制数
2023-06-17

jvm类加载器,类加载机制是什么

这篇文章主要介绍“jvm类加载器,类加载机制是什么”,在日常操作中,相信很多人在jvm类加载器,类加载机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jvm类加载器,类加载机制是什么”的疑惑有所帮助!
2023-06-16

java什么时候出的

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。 (推荐学习:java课程)Java语言作为静态面向对象编程语言的代
java什么时候出的
2020-09-18

JAVA类的加载过程是什么

JAVA类的加载过程主要分为加载、链接和初始化三个阶段。加载:类加载是指将类的.class文件从文件系统或网络加载到内存中,并为之创建一个Class对象。类加载器通过类的全限定名来定位并读取对应的.class文件,并将其转换为字节码流,然后
2023-10-26

java类的加载的过程是什么

Java类的加载过程包括以下步骤:加载(Loading):将类的字节码文件加载到内存中。这个阶段由类加载器完成,类加载器将字节码文件从磁盘或网络读取到内存,并创建一个对应的Class对象。验证(Verification):验证字节码文件的合
java类的加载的过程是什么
2023-10-28

tomcat类加载机制是什么

Tomcat的类加载机制是指Tomcat服务器在运行过程中,如何加载和管理Java类文件的过程。它主要包括以下几个步骤:1. Bootstrap类加载器:Tomcat的启动类加载器,负责加载Tomcat自身的核心类,如Catalina和Co
2023-09-15

Java中类的加载顺序是什么

本篇文章为大家展示了Java中类的加载顺序是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。具体如下:public class Parent { public static int a = pa
2023-05-31

Java匿名内部类在什么时候用

Java匿名内部类通常在以下情况下使用:1. 当一个类只需要使用一次,并且这个类没有名字,可以使用匿名内部类来实现。这样可以避免创建一个单独的类文件。2. 当一个接口只有一个方法需要实现时,可以使用匿名内部类来实现接口的方法。这种情况下,可
2023-08-15

Java中的类加载是什么意思

本篇内容主要讲解“Java中的类加载是什么意思”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中的类加载是什么意思”吧!目录1.类加载<1>.父子类执行的顺序<2>类加载的时机<3>类的生
2023-06-20

Java类加载器的特色是什么

这篇文章主要介绍“Java类加载器的特色是什么”,在日常操作中,相信很多人在Java类加载器的特色是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java类加载器的特色是什么”的疑惑有所帮助!接下来,请跟
2023-06-15

Java 中 static 变量在类加载时究竟做了哪些事情?(java static变量在类加载时做了什么)

在Java编程中,static变量是一个非常重要的概念。它具有独特的生命周期和作用域,并且在类加载时会执行一些特定的操作。本文将深入探讨Java中static变量在类加载时所做的事情。一、类加载过程
Java 中 static 变量在类加载时究竟做了哪些事情?(java static变量在类加载时做了什么)
Java2024-12-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录