第13篇:Java继承的内存布局

简介: 🍀 ① 加载类信息: 会先加载当前类的父类的类信息(包括 Object 基类)🍀 ② Son 对象中会拥有其所有父类的属性: 父类属性和子类属性名字一样是可以的🍀 ③ 访问属性的时候:先看当前类中是否有该属性?若有,直接访问;⚡ 若没有,查看直接父类是否有该属性,并且该属性是否可访问?若有并且属性没有被 private 修饰,可访问直接父类的属性;⚡ 若有但属性被 private 修饰,直接报错;⚡ 若没有,继续查找父类的父类是否有该属性,并且是否可访问 ...【① 看自己有没有,有就直接用;若自己没有,就看父亲有没有,若父亲没有,就看爷爷有没有,... 一直向上找,直达找到 Obj

一、初步了解继承的内存布局

(1) 继承内存布局初探

看下面拥有继承关系的代码,并画出内存布局图:

public class Person {
    public int age;

    public void smile() {
        System.out.println("Person_smile()_age_" + age);
    }
}

class Student extends Person {
    public double score;

    public void study() {
        System.out.println("Student_study()_score_" + score);
    }
}

class MainTest {
    public static void main(String[] args) {
        Student s = new Student();
        s.score = 95.5;
        s.age = 8;
        // Person_smile()_age_8
        s.smile();
        // Student_study()_score_95.5
        s.study();

        Person p = new Person();
        p.age = 15;
        // Person_smile()_age_15
        p.smile();
    }
}
⌨️ 通过 上篇文章 可以知道:Student 类通过 extends 关键字继承了 Person 类后,Student 类中便拥有了 Person 类中非 private 的成员变量和成员方法。因此,Student 对象的引用 student 可以访问到父类(Person)的 age 属性和 smile 方法 😊

继承的内存布局图:
在这里插入图片描述

⌨️ Student 类继承 Person 类后会拥有 Person 类中的 age 属性,age 属性在 Student 对象的内存中也拥有一份
⌨️ Student 对象的内存和 Person 对象的内存各种独占,互不干扰

(2) Object 类

📙 任何类最终都继承自 java.lang.Object 类(Object 类叫做基类
在这里插入图片描述


📙 The Object class, in the java.lang package, sits at the top of the class hierarchy(层次体系) tree. Every class is a descendant(派生、后代), direct or indirect, of the Object class.

📙【翻译】 java.lang 包中的 Object 类位于类继承体系数的顶端。每一个类都是 Object 类的直接或间接派生类(子类)。


(3) 同名的成员变量

Java 允许子类定义和父类同名的成员变量(不推荐

public class Person {
    public int money = 10000;
}

class Teacher extends Person {
    public int money = 22222;

    public void show() {
        System.out.println("money: " + money);
        System.out.println("this.money: " + this.money);
        System.out.println("super.money: " + super.money);
    }
}

class Main {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        t.show();

        /*
            output:
                money: 22222
                this.money: 22222
                super.money: 10000
         */
    }
}

上面代码的内存布局:
在这里插入图片描述

二、更复杂的继承的内存布局

看下面的代码,话它的内存布局图:

public class Test {
    public static void main(String[] args) {
        Son son = new Son();
    }
}

class Grandfather {
    String name = "Grandfather_name";
    String hobby = "Grandfather_hobby";
}

class Father extends Grandfather {
    String name = "Father_name";
    int money = 66666;
}

class Son extends Father {
    String name = "Son_name";
}

在这里插入图片描述

🍀 ① 加载类信息: 会先加载当前类的父类的类信息(包括 Object 基类)
🍀 ② Son 对象中会拥有其所有父类的属性: 父类属性和子类属性名字一样是可以的
🍀 ③ 访问属性的时候:先看当前类中是否有该属性?若有,直接访问;⚡ 若没有,查看直接父类是否有该属性,并且该属性是否可访问? 若有并且属性没有被 private 修饰,可访问直接父类的属性;⚡ 若有但属性被 private 修饰,直接报错;⚡ 若没有,继续查找父类的父类是否有该属性,并且是否可访问 ...【 ① 看自己有没有,有就直接用;若自己没有,就看父亲有没有,若父亲没有,就看爷爷有没有,... 一直向上找,直达找到 Object; ② 若中途发现有一关系有该属性,但是不能被访问(被 private 修饰),直接报错,不继续往下找了

1.父类的属性被 private 修饰,无法访问,但可通过其他方式访问(如:父类提供被 public 修饰的 get 方法)
2.私有的属性在内存中依然存在,只是无法被访问而已

🎈再见!若有错误,请不吝赐教!🎈

相关文章
|
12天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
106 1
|
1天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
1天前
|
存储 安全 Java
什么是 Java 的内存模型?
Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范的一部分,它定义了一套规则,用于指导Java程序中变量的访问和内存交互方式。
8 1
|
7天前
|
存储 运维 Java
💻Java零基础:深入了解Java内存机制
【10月更文挑战第18天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
21 1
|
10天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
12 3
|
10天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
24 2
|
10天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
22 2
|
10天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
10天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
22 1
|
17天前
|
存储 监控 算法
Java中的内存管理与垃圾回收机制解析
本文深入探讨了Java编程语言中的内存管理方式,特别是垃圾回收机制。我们将了解Java的自动内存管理是如何工作的,它如何帮助开发者避免常见的内存泄漏问题。通过分析不同垃圾回收算法(如标记-清除、复制和标记-整理)以及JVM如何选择合适的垃圾回收策略,本文旨在帮助Java开发者更好地理解和优化应用程序的性能。