Java 中父子类同名字段的隐藏机制与对象内存布局解析

冬敏君_2190

冬敏君_2190

2026-01-14

952人浏览

原创

Java 中父子类同名字段的隐藏机制与对象内存布局解析

java 子类声明与父类同名字段时,并非覆盖,而是**字段隐藏(field hiding)**:子类对象在内存中实际包含两份独立的 `x` 字段(`parent.x` 和 `child.x`),分别由各自构造器初始化,通过 `this.x` 和 `super.x` 可明确访问不同副本。

在 Java 中,当子类 C 继承父类 P 并定义了同名字段(如 int x;),这并非“重写”或“覆盖”,而是一种明确的语言特性——字段隐藏(Field Hiding),由《Java 语言规范》(JLS §8.3)明确定义:子类中同名字段会隐藏所有可访问的父类同名字段。关键在于:隐藏 ≠ 合并,它导致同一个对象实例中物理存在两个独立的 x 字段,分别隶属于父类和子类的继承层级。

内存结构:一个对象,两份字段

虽然 new C() 只创建一个对象实例,但该实例的内存布局包含:

  • 父类部分(P 的字段):含 P.x,初始值为 1(由 P() 构造器设置);
  • 子类扩展部分(C 的字段):含 C.x,初始值为 2(由 C() 构造器设置)。

二者在内存中是完全独立的变量,占据不同偏移地址,互不干扰。

访问规则决定输出差异

你观察到的输出:

java-api-doc-generator
java-api-doc-generator

分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。

下载
c.x: 2
c.getX(): 1

正是字段隐藏行为的直接体现:

  • c.x → 编译期根据变量静态类型 C 解析,访问的是 C.x(值为 2);
  • c.getX() → getX() 在 P 中定义,其方法体中的 x 指代的是 P 类作用域内的 x(即 P.x),因此返回 1。

✅ 正确访问双字段的示例:

class Child extends Parent {
    int x;

    Child() {
        super(); // 显式调用父构造器(可省略,但强调执行顺序)
        this.x = 2;   // 初始化 Child.x
    }

    void printBothXs() {
        System.out.println("this.x (Child.x): " + this.x);     // 输出 2
        System.out.println("super.x (Parent.x): " + super.x); // 输出 1
    }
}

重要注意事项

  • ❌ 无法从外部类直接访问 super.x:c.super.x 是非法语法。super 关键字仅在子类非静态方法/构造器内部有效;
  • ⚠️ 避免字段隐藏:这是易出错的设计陷阱。推荐使用不同字段名,或通过 protected 字段 + getter/setter 统一管理;
  • ? 构造器执行顺序:new C() 时,JVM 严格按 P() → C() 顺序执行,确保父类字段先初始化,但不会覆盖子类同名字段;
  • ? 与方法重写的本质区别:方法可被重写(动态绑定),字段只能被隐藏(静态绑定)。这是理解本问题的核心分水岭。

总结来说,Java 的字段隐藏机制让单个对象能安全容纳多份同名字段,提升继承灵活性,但也要求开发者清晰区分 this. 与 super. 的语义边界——这不是 bug,而是 JLS 精心设计的、可预测的语言特性。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java 作用域

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

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

2023.08.02

6919

3

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

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

2024.08.29

3325

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

4328

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2945

10

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

80

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

60

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

220

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

140

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

120

10

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习