0

0

Java里的类加载顺序是怎样的_父子类静态变量与构造器实战

P粉602998670

P粉602998670

发布时间:2026-03-02 13:43:02

|

501人浏览过

|

来源于php中文网

原创

java里的类加载顺序是怎样的_父子类静态变量与构造器实战

父类静态变量和静态代码块先于子类执行

Java 类加载时,静态成员按「类声明顺序」在类初始化阶段执行,且父类优先于子类。这不是编译期决定的,而是 JVM 在首次主动使用该类(比如 new、调用静态方法、访问静态字段等)时触发类初始化,此时会递归确保父类已初始化。

常见错误现象:NullPointerException 出现在子类静态字段里,只因它引用了尚未初始化完成的父类静态字段——其实不是“未初始化”,而是父类静态块还没轮到执行完。

  • 父类 static 变量赋值 → 父类 static 代码块 → 子类 static 变量赋值 → 子类 static 代码块
  • 如果父类静态块里调用了子类的静态方法,会导致子类提前初始化(即“被动触发”),但此时子类的静态变量可能还未赋值(只声明、未初始化),结果是默认值(如 null0
  • ClassLoader.loadClass("X") 不会触发初始化;只有 Class.forName("X")(无参)或显式访问才会

构造器调用链:从 Object 到子类,不跨过父类构造器

每次 new 实例,JVM 强制要求子类构造器第一行必须是 super()this() 调用(哪怕没写,编译器自动补 super())。这意味着构造器执行顺序和继承链完全一致,且无法跳过中间某层。

容易踩的坑:在父类构造器里调用被子类重写的方法,此时子类实例字段还未初始化(仍是默认值),但方法体已执行子类版本——这是典型的“过早暴露 this”问题。

立即学习Java免费学习笔记(深入)”;

  • 执行顺序:父类实例变量赋值 → 父类构造器体 → 子类实例变量赋值 → 子类构造器体
  • 父类构造器中调用 method(),而子类重写了它,JVM 仍走动态绑定,执行子类方法,但此时 this.field 是默认值(如 null
  • 避免在构造器中调用非 private / 非 final 方法,尤其不要依赖子类字段状态

静态变量 vs 实例变量:初始化时机差一个「类加载阶段」

静态变量属于类,随类初始化完成;实例变量属于对象,每次 new 时才分配并初始化。两者生命周期、作用域、触发时机完全不同,混用会导致意料外的 null 或旧值残留。

VisualizeAI
VisualizeAI

用AI把你的想法变成现实

下载

典型场景:工具类里用静态 Map 缓存数据,但 Map 的 key 是某个子类实例 —— 如果这个子类还没被加载,那它的 class 对象都不存在,更别说作为 key 安全使用了。

  • 静态变量在类初始化时完成(一次),实例变量在每次构造器执行中完成(多次)
  • 子类继承父类静态变量,但不会重新初始化;而继承的实例变量会在每次 new 子类时重新赋值
  • 若静态变量是可变对象(如 static List<string> cache = new ArrayList()</string>),多个子类实例共享同一份引用,要注意线程安全与污染风险

实战验证:用 System.out.println 打点看真实顺序

别猜,直接打印。JVM 规范写得清楚,但具体到你的代码,唯一可信的是日志输出。重点打在静态变量声明处、静态块、构造器开头——注意别打在字段初始化表达式里(如 int x = logAndReturn(1)),那会干扰判断。

示例片段:

class A {
    static { System.out.println("A static"); }
    { System.out.println("A init"); }
    A() { System.out.println("A ctor"); }
}
class B extends A {
    static { System.out.println("B static"); }
    { System.out.println("B init"); }
    B() { System.out.println("B ctor"); }
}
// 输出一定是:
// A static
// B static
// A init
// A ctor
// B init
// B ctor

如果实际输出不符,大概率是类被多次加载(不同 ClassLoader)、或有 static final 编译期常量导致提前内联——这时候就得查类加载器和字节码了。

最复杂也最容易被忽略的点:同一个类被两个不同的 ClassLoader 加载,它们的静态变量完全隔离,互不影响。这种情况下,“父子类”关系只在源码层面成立,在运行时可能是两套独立的类体系。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

910

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

249

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

967

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1560

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1560

2023.10.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1560

2023.10.24

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

910

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

596

2024.08.29

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

48

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4万人学习

C# 教程
C# 教程

共94课时 | 10.5万人学习

Java 教程
Java 教程

共578课时 | 75.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号