Office 365中的Device Management详细功能介绍
2026/6/18 22:44:09
Java 中有两种不同的 “构造方法”,二者的作用、执行时机完全无关:
| 构造方法类型 | 名称(字节码层面) | 通俗理解 | 手动定义方式 | 核心作用 |
|---|---|---|---|---|
| 类构造方法 | <clinit>() | 静态构造器、类初始化方法 | 无需手动定义(编译器自动生成) | 初始化类的静态资源(静态变量、静态代码块) |
| 实例构造方法 | <init>() | 对象构造器、构造函数 | public 类名(...) { ... } | 初始化对象的实例资源(实例变量、实例代码块) |
<clinit>(),不执行实例构造方法<init>()类加载的「初始化阶段」是类加载流程的第 5 步(加载→验证→准备→解析→初始化),其核心任务就是执行类构造方法<clinit>(),而实例构造方法<init>()与类加载无关,仅在创建对象(new关键字、反射等)时执行。
<clinit>()的核心特性static{})」按书写顺序合并生成,无需开发者手动定义;<clinit>()方法在多线程环境下被同步执行,且仅执行一次(类初始化的原子性);<clinit>()方法,再执行当前类的<clinit>();Class.forName()间接触发);<clinit>()方法,初始化阶段无需执行任何操作。<init>()的执行时机实例构造方法<init>()是对象实例化阶段的方法,与类加载的初始化阶段无关,只有通过以下方式创建对象时才会执行:
new 类名():直接创建对象;Class.newInstance()(已过时)、Constructor.newInstance();Object.clone()(需实现Cloneable接口)。<clinit>()(静态资源初始化)java
运行
public class ClassInitDemo { // 1. 静态变量显式赋值(会被收集到<clinit>()中) private static int staticVar = initStaticVar(); // 2. 静态代码块(会被收集到<clinit>()中,按书写顺序执行) static { System.out.println("类初始化:执行静态代码块"); staticVar += 10; } // 静态变量初始化方法 private static int initStaticVar() { System.out.println("类初始化:执行静态变量赋值方法"); return 5; } // 3. 实例构造方法(<init>(),类初始化阶段不执行) public ClassInitDemo() { System.out.println("对象实例化:执行实例构造方法"); this.instanceVar = 20; } // 实例变量(与类初始化无关) private int instanceVar; public static void main(String[] args) { System.out.println("===== 开始执行main方法(触发类初始化) ====="); System.out.println("静态变量值:" + ClassInitDemo.staticVar); System.out.println("\n===== 创建对象(触发实例构造方法) ====="); new ClassInitDemo(); } }plaintext
类初始化:执行静态变量赋值方法 类初始化:执行静态代码块 ===== 开始执行main方法(触发类初始化) ===== 静态变量值:15 ===== 创建对象(触发实例构造方法) ===== 对象实例化:执行实例构造方法main方法调用ClassInitDemo.staticVar触发类的主动使用,进入类初始化阶段;<clinit>()方法,按顺序执行「静态变量赋值」和「静态代码块」,输出前两行日志;main方法中的打印语句;new ClassInitDemo()时,才会调用实例构造方法<init>(),输出对象实例化日志,这一步与类加载的初始化阶段无关。<clinit>()仅执行一次java
运行
public class ClinitOnceDemo { static { System.out.println("类初始化:<clinit>() 执行"); } public ClinitOnceDemo() { System.out.println("对象实例化:<init>() 执行"); } public static void main(String[] args) { // 第一次创建对象:先触发类初始化(<clinit>()执行),再执行<init>() new ClinitOnceDemo(); // 第二次创建对象:仅执行<init>(),<clinit>()不再执行 new ClinitOnceDemo(); // 第三次创建对象:仍仅执行<init>() new ClinitOnceDemo(); } }plaintext
类初始化:<clinit>() 执行 对象实例化:<init>() 执行 对象实例化:<init>() 执行 对象实例化:<init>() 执行<clinit>()方法仅在第一次主动使用时执行一次,后续无论创建多少个对象,都不会再执行;<init>()每次创建对象时都会执行,与类初始化阶段无关。只有满足「主动使用」条件时,JVM 才会触发类的初始化(执行<clinit>()),常见主动使用场景包括:
new关键字创建类的实例;final修饰,final静态常量存入常量池,属于被动使用);Class.forName("类全限定名"))主动加载类;main()方法的主类(程序入口类,必然会被初始化)。<init>(),即平时写的构造函数),仅执行类构造方法(<clinit>());<clinit>()是编译器自动生成的,用于初始化静态变量和静态代码块,仅执行一次;<init>()用于初始化对象的实例资源,仅在创建对象(new/ 反射等)时执行,与类加载流程无关;<clinit>(),保证类的静态资源完成初始化。