【java】类的加载和对象的构造(实例化)过程及顺序 电玩女神 2023-08-17 15:58 91阅读 0赞 ### 1.类的加载 ### **1.1 什么类的加载load?(Node类的加载)** 答.从硬盘上找到Node.class,解析该文件内容,生成Node类,把Node类的信息存放在内存的方法区 **1.2 什么情况下回触发类的加载?并且该类不在内存中** (1)按需加载(懒加载过程) a.实例化该类的一个对象 new Node(1); b.使用类的静态属性或者静态方法 Main.merge(…) c.用到子类,必须要有父类 new CNode d.先加载父类的静态代码块,再加载子类的静态代码块 **1.3 其他规则** 静态属性的初始化顺序: 按代码的书写顺序,执行 a.静态属性定义时的初始化 b.静态代码 ## 2.代码块 ## 代码块定义:使用“\{\}”定义的一段代码; 构造代码块是跟着对象的加载而加载的。 **2.1 普通代码块** 普通代码块:定义在方法中的代码块; public class Test1 { public static void main(String[] args) { { //普通代码块 int a=10; System.out.println(a); } int a=20; System.out.println(a); } } ![20190927165433394.png][] **2.2 构造块** 构造块:定义在类中的代码块(不加修饰符) class A{ //定义在类中,不加任意修饰符 { System.out.println("A的构造块"); } //构造方法 public A(){ System.out.println("A的构造方法"); } } public class Test2 { public static void main(String[] args) { new A(); new A(); } } ![20190927171026622.png][] 通过上述代码可以发现:构造块优先于构造方法执行,每产生一个新的对象就调用一次构造块。所以构造块可以进行简单的逻辑操作(在调用构造方法之前)。 **2.3 静态代码块** 静态代码块:使用static定义的代码块,它是跟着类的加载而加载的。 根据静态代码块所在的类不同又可分为以下两种类型: 1.在非主类中的静态代码块 2.在主类中的静态代码块 **2.3.1 在非主类中的静态代码块** class B{ //构造块 { System.out.println("B类的构造块"); } //代码方法 public B(){ System.out.println("B类的构造方法"); } //静态代码块 static { System.out.println("B类的静态代码块"); } } public class Test3 { public static void main(String[] args) { System.out.println("=============================="); new B(); new B(); System.out.println("=============================="); } } ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjY5MDA3_size_16_color_FFFFFF_t_70][] 可以发现: 1.在非主类的静态代码块中,在类加载时执行,优先于构造块执行 2.无论产生多少实例化对象,静态代码块只执行一次 静态块的主要作用是为static属性进行初始化! **2.3.2 在主类中的静态代码块** public class Test4 { //构造块 { System.out.println("Test4类的构造块"); } //构造方法 public Test4(){ System.out.println("Test4类的构造方法"); } //静态代码块 static { System.out.println("Test4类的静态代码块"); } public static void main(String[] args) { System.out.println("==========================="); new Test4(); new Test4(); System.out.println("==========================="); } } ![20190927173304492.png][] 在主类中定义的静态块,优先于主方法(main)执行,在JVM启动时执行,当编译执行时JVM会首先加载主类,此时主类中的静态代码块就会执行。 ## 3.对象的构造/实例化 new Node ## **3.1 规则** 1.优先初始化父类的属性,(和下面的执行顺序相同) 2.按照下面的顺序执行初始化 a.按照代码书写顺序,执行定义时和构造代码块 b.再去执行构造方法 3.静态代码块只在加载时执行一次,先执行父类的静态代码块,再执行子类的静态代码块。 **3.2关于执行顺序的问题** 1.父类的加载在子类之前 2.父类的构造方法在子类之前调用 3.static属性初始化是在类的加载时执行(按顺序执行) 1)定义时初始化 2)构造代码块时初始化 4.普通属性初始化是在对象的构造时执行(按顺序执行) 1)定义时初始化 2)构造代码块时初始化 3)构造方法时初始化 5.只有用到类,才会加载类 class Hello{ //构造方法 public Hello(){ System.out.println("1.Hello父类的构造方法"); } //非静态代码块 { System.out.println("2.Hello父类非静态代码块"); } //静态代码块 static{ System.out.println("3.Hello父类静态代码块"); } } public class HelloA extends Hello{ public HelloA(){ System.out.println("4.helloA构造方法"); } //非静态代码块 { System.out.println("5.HelloA非静态代码块"); } //静态代码块 static{ System.out.println("6.HelloA静态代码块"); } public static void main(String[] args) { System.out.println("7.---start---"); new HelloA(); new HelloA(); System.out.println("8.---end---"); } } 按照上面讲的执行顺序执行:因为先用到了主类HeoolA,所以先加载了静态代码块; 执行结果: ![20190927232315814.png][] class Hello1{ //构造方法 public Hello1(){ System.out.println("1.Hello1父类的构造方法"); } //非静态代码块 { System.out.println("2.Hello1父类非静态代码块"); } //静态代码块 static{ System.out.println("3.Hello1父类静态代码块"); } } class Hello2 extends Hello1 { public Hello2() { System.out.println("4.hello2构造方法"); } //非静态代码块 { System.out.println("5.Hello2非静态代码块"); } //静态代码块 static { System.out.println("6.Hello2静态代码块"); } } public class Test{ public static void main(String[] args) { System.out.println("7.---start---"); new Hello2(); new Hello2(); System.out.println("8.---end---"); } } 运行结果: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjY5MDA3_size_16_color_FFFFFF_t_70 1][] 注:[代码块的内容参考本文章][Link 1]!!! [20190927165433394.png]: /images/20230810/f370b2a315814b258fa0bd383a6ad264.png [20190927171026622.png]: /images/20230810/38adb1817ac44952b9abc9d2cd6c5ea8.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjY5MDA3_size_16_color_FFFFFF_t_70]: /images/20230810/458ea1d2f4304962874522f96fcedfdd.png [20190927173304492.png]: /images/20230810/3cec596f72404af58e2d8a8e1dc22e6c.png [20190927232315814.png]: /images/20230810/00af7d4fdca3466992b70d1d86badc4d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjY5MDA3_size_16_color_FFFFFF_t_70 1]: /images/20230810/70875aaf83a24369b8b02aadf4ee373d.png [Link 1]: https://blog.csdn.net/zhao_miao/article/details/83215956
相关 混淆类加载顺序:Java类加载过程中的常见问题 在Java类加载过程中,可能会遇到以下常见的问题: 1. 类加载顺序: - 首先,JVM启动时会从Bootstrap Classpath(系统路径)中查找字节码文件。 喜欢ヅ旅行/ 2024年09月15日 12:12/ 0 赞/ 74 阅读
相关 类加载顺序问题:Java类的加载路径和顺序案例 在Java中,类的加载是通过Java虚拟机(JVM)来实现的。加载路径和顺序主要体现在以下几个方面: 1. **内置类**:所有Java语言定义的内置类(如Object、St Love The Way You Lie/ 2024年09月10日 13:30/ 0 赞/ 89 阅读
相关 Java 类加载机制与对象实例化 文章目录 * 1. 类加载机制 * * * 1.1. 类加载器与类的唯一性 * 1.2. 类加载器种类 * 1... 蔚落/ 2024年04月18日 12:53/ 0 赞/ 70 阅读
相关 Java类的加载及父类子类加载顺序 > 点击 [Mr.绵羊的知识星球][Mr.] 解锁更多优质文章。 目录 一、类的加载 1. 类加载 2. 类加载器 二、父类和子类加载顺序 1. 案例(代码) - 太过爱你忘了你带给我的痛/ 2024年03月30日 16:10/ 0 赞/ 73 阅读
相关 【java】类的加载和对象的构造(实例化)过程及顺序 1.类的加载 1.1 什么类的加载load?(Node类的加载) 答.从硬盘上找到Node.class,解析该文件内容,生成Node类,把Node类的信息存放在内存的方 电玩女神/ 2023年08月17日 15:58/ 0 赞/ 92 阅读
相关 java反射-类实例化和类加载 转自:[https://www.cnblogs.com/throwable/p/12272269.html][https_www.cnblogs.com_throwable_ 悠悠/ 2023年01月17日 07:43/ 0 赞/ 166 阅读
相关 Java 理解类的加载机制 类加载顺序 类初始化过程 实例初始化过程 一、代码如下 1、创建一个Father类,包含实例变量、静态变量、静态代码块、构造方法、构造代码块、实例方法、静态方法 @Description: 电玩女神/ 2022年08月28日 08:51/ 0 赞/ 296 阅读
相关 Java类的加载和实例化全过程解析 Java类的加载和实例化全过程解析 1.类加载 1.1 类加载器选择 1.2 类装载 1.3 类验证 1.4 超、凢脫俗/ 2022年01月12日 02:05/ 0 赞/ 239 阅读
相关 Java类初始化和对象实例化顺序 这里只考虑在一个类的情况下类初始化和对象实例化的顺序,不考虑有父类的情况下。 看下面这段代码: package com.huang.jvm; / 小咪咪/ 2021年11月19日 14:48/ 0 赞/ 415 阅读
还没有评论,来说两句吧...