当前位置: 首页 > news >正文

JVM类的加载

一、如何定义类的初始化段

类的初始化段(也称为静态初始化块)是用于在类加载时执行初始化逻辑的代码块,定义方式是在代码块前加 static 关键字。它属于类级别的初始化,只在类被加载并初始化时执行一次,用于初始化静态变量或执行类级别的预处理逻辑。

语法示例:

public class MyClass {// 静态变量private static int count;// 静态初始化块(类的初始化段)static {System.out.println("类初始化段执行");count = 10; // 初始化静态变量}// 普通成员变量private int num;// 普通初始化块(实例初始化段,不属于类初始化){System.out.println("实例初始化段执行");num = 20; // 初始化实例变量}public static void main(String[] args) {System.out.println("main方法执行");System.out.println("count = " + count); // 访问静态变量}
}

说明:

  • 静态初始化块(类初始化段):由 static {} 定义,属于类本身,在类加载并初始化时执行,且只执行一次(无论创建多少对象)。
  • 普通初始化块:由 {} 定义,属于实例,每次创建对象时会在构造方法之前执行,用于初始化实例变量(非静态)。

二、类的加载、初始化与 main 方法的执行顺序

是的,类会先完成加载和初始化,然后才执行 main 方法。具体流程如下:

  1. 类加载:JVM 首次遇到某个类时(如执行 main 方法所在的类),会将其字节码加载到内存中(类加载过程)。
  2. 类初始化:加载完成后,JVM 会执行类的初始化逻辑,包括:
    • 静态变量的声明与赋值(如 private static int count = 5;)。
    • 静态初始化块(类的初始化段)中的代码,按定义顺序执行。
  3. 执行 main 方法:类初始化完成后,JVM 才会调用该类的 static main 方法,作为程序入口。

验证示例

运行上面的 MyClass,输出顺序为:

plaintext

类初始化段执行  // 类初始化时执行
main方法执行     // 类初始化完成后,执行main方法
count = 10

如果在 main 方法中创建对象:

java

运行

public static void main(String[] args) {System.out.println("main方法执行");MyClass obj = new MyClass(); // 创建对象
}

输出顺序为:

plaintext

类初始化段执行  // 类先初始化
main方法执行     // 执行main
实例初始化段执行 // 创建对象时,执行实例初始化块(在构造方法前)

总结

  1. 类的初始化段(静态初始化块)通过 static {} 定义,用于类加载时的初始化,只执行一次。
  2. 程序启动时,JVM 会先加载并初始化包含 main 方法的类(执行静态变量赋值和静态初始化块),完成后才会调用 main 方法
  3. 实例初始化块(普通初始化块)属于对象,在每次创建对象时执行,与类的加载 / 初始化阶段无关。

因为这种机制,包含main方法的类可以在main方法中直接创建本类的实例,即使创建实例后边有其他代码也无所谓,因为java是先加载完类的所有编译完的字节码放到内存中,在实例化的时候已经知道类的所有代码,而不是像python读一行操作一行

1. Java 是 “预编译 + 类加载” 机制,而非 “逐行解释执行”

Java 代码需要先编译成字节码(.class 文件),再由 JVM 加载到内存中执行。在类加载阶段,JVM 会完整解析类的所有结构(包括类名、父类、方法、字段、构造器等),并将这些信息存入方法区(元空间)。这意味着:当执行 main 方法时,JVM 已经 “知道” 这个类的所有定义(包括自身的构造器、方法等),无论实例化代码写在类的哪个位置(即使在 main 方法中间,甚至在类的后半部分定义构造器),JVM 都能找到对应的结构并创建实例。

例如,即使代码写成这样,也能正常运行:

public class Test {public static void main(String[] args) {Test t = new Test(); // 这里创建实例时,JVM 已经知道 Test 类的所有定义t.print();}// 方法定义在 main 之后,但不影响调用public void print() {System.out.println("Hello");}
}

2. Python 是 “逐行解释执行”,依赖 “提前声明”

Python 是解释型语言,没有预编译阶段,代码从上到下逐行执行。如果在定义类的实例或调用方法之前,解释器还没 “读到” 类的完整定义,就会报错。例如,下面的 Python 代码会报错(因为创建实例时,Test 类还未定义完成):

t = Test()  # 报错:NameError: name 'Test' is not definedclass Test:def print(self):print("Hello")

必须先定义类,再创建实例,这是由逐行解释的机制决定的。

总结

Java 之所以允许在 main 方法中直接创建本类实例(无论代码顺序如何),核心原因是:类在执行 main 方法之前,已经通过编译和加载过程被完整解析到内存中,JVM 对类的所有结构(包括自身)已有完整认知,而不像 Python 那样依赖代码的逐行执行顺序。这种机制保证了 Java 中类的 “自引用”(如在自身方法中创建实例)不会因代码位置而出现问题。

http://www.dtcms.com/a/487710.html

相关文章:

  • ui设计学习公司网站的seo优化怎么做
  • 网站开发的流程和步骤是什么免费seo网站优化
  • 分库分表下如何实现分页查询功能
  • 江苏弘盛建设工程集团有限公司网站好看企业官网源码
  • LVDS系列31:Xilinx 7系 ADC LVDS接口参考设计(二)
  • 网站建设是什么?进入百度网首页
  • 【HackTheBox】- Busqueda 靶机学习
  • 127.XIlinx fpga端的pcie(XDMA)与驱动是如何交换数据的
  • 个人网站名称怎么起济南的互联网公司有哪些
  • 在Docker中pip离线安装python的各种包
  • 建设电子商务网站的方法有?网站开发软件三剑客
  • 企业网站管理系统(多语言+多模板)
  • 设计师去哪个网站找工作wordpress linux下载
  • 机器学习入门,无监督学习之K-Means聚类算法完全指南:面向Java开发者的Python实现详解
  • Java 设计模式——代理模式:从静态代理到 Spring AOP 最优实现
  • 网站制作公司属于广告发布者吗自己买服务器搭建网站
  • 有哪些好的建站平台泰兴企业网站建设
  • 阜宁专业做网站广告推广广告
  • 网站建设多少钱需要wordpress商品展示插件
  • c语言位运算 汇编代码分析
  • 民制作网站哪家便宜西安单位网站制作
  • 云南网站开发建设大丰网站建设价格
  • 横山桥网站网站用户群
  • 制作网站培训长沙seo招聘
  • 两阶段不确定性优化:一种用于解决“现在决策、未来见效”问题的强大建模框架。
  • 香港虚拟主机和香港云服务器哪个更安全?
  • 苏州网站建设案例什么是电子商务网站推广
  • 浙江建筑网站南上海网站建设
  • 制作企业网站需要注意的事项wordpress 重装
  • 个人怎么做淘宝客网站seo网站推广的主要目的