继承的内存分析

首先了解java中this和super关键字,this来引用当前对象,super来引用直接父类,并且在每个方法中都隐藏了this和super变量。super()方法都会出现在子类构造方法的第一行,如果不写,编译器会自动帮我们隐藏添加。现在我们来分析下面的代码:

package generic;

public class Animal {

    public Animal(){
        super();
        System.out.println("Animal.Animal()");
    }

    public void run(){
        System.out.println("Animal.run()");
    }

    public void voice(){
        System.out.println("Animal.voice()");
    }

    public static void main(String[] args) {
        Bird a = new Bird();
        a.run();
    }
}

class Bird extends Animal{
    public Bird(){
        super();
        System.out.println("Bird.Bird()");
    }

    public void run(){
        System.out.println("Bird.run()");
    }
}

分析任何程序都是从main方法的第一句话开始,所以首先分析main的第一句话

Animal a = new Bird();

这句话运行后,会在栈空间里面产生一个a变量,具体值还不确定(要等到new Bird()运行完后才能确定),运行new Bird()时,因为new Bird方法的第一句有super()方法,会去调用它的直接父类,所以会去Animal类中调用Animal(),同理Animal又会去调用它的直接父类Object。调用的过程如下图所示

在Object()方法运行完后,就会在堆区间中生成Object对象,并且继续执行Animal()方法后面的代码(这过程相当于递归),生成Animal对象,最后才生成Bird对象,并且将地址赋给a变量a。通过这个分析也能说明为什么是Animal.Animal()先输出来。内存分配图如下:

这时a指向的是bird对象,在调用第二句时,所以会在bird对象中找是否会有run这个方法,如果找到就不再去父类中查找。

时间: 2024-08-24 19:00:01

继承的内存分析的相关文章

java执行程序的内存分析系列专栏

近段时间研究了java的程序执行过程中的内存分配,收获颇多,解决了我最近时间学习java的很多困惑点.写java内存分析系列的目的主要有两个,一来是希望给像我一样的java初学者一定的启发,希望也能解决的java关于内存方面的困惑点.二来也是给自己做个总结,毕竟只有自己亲自写出来的东西,才是真正的东西.今天就开始java程序执行过程内存分析系列第一篇. 一. java执行程序时内存的划分 一般来说,作为初学者,一般只是将java程序的内存只是分为栈区,和堆区.确实刚开始学时这样划分能都便于我们理

面向对象编程(十)——继承之Super关键字及内存分析

阅读目录 Super关键字画内存分析图了解程序执行的整个过程 Super关键字 在JAVA类中使用super来引用父类的成分,用this来引用当前对象,如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象.怎么去引用里面的父类对象呢?使用super来引用,this指的是当前对象的引用,super是当前对象里面的父对象的引用. super是直接父类对象的引用.可以通过super来访问父类中被子类覆盖的方法或属性. (注意和this的区别:this是当前对

黑马程序员————子父类中成员变量的内存分析

对于java单个类的内存分析相信大家都了解,但是如果结合继承,子类与父类是如何存在在内存中的呢,他们的先后调用关系又改是怎样的呢? 首先简单介绍一下对象的初始化过程,比如这个简单的例子 class Student{ int i =20; String name="李四"; static{ System.out.println("我是静态代码块"); } { System.out.println("我是构造代码块"); } void print()

Java内存分析

前言 只看代码,我们只能了解程序执行的先后顺序,通过内存分析,我们可以了解程序执行过程中的内存分配情况.前者是在时间维度上进行分析,后者是在空间维度上进行分析.本文目的就是将具体代码与其执行过程中的内存分配情况对应起来,使大家对这块内容有个清晰的认识. 概述 根据下图,我们首先来介绍一下整个程序执行过程.主要分为三步: 双击程序文件,将程序装载到内存中: 内存中本身有操作系统的代码,会找到代码中的main方法开始执行: 执行过程中的内存管理. 补充: 程序文件本身放在硬盘上,文件扩展名可以是.e

J2SE快速进阶——向上转型及其内存分析

还记得刚通过C#学习面向对象时,接触了对象转型,最近学习Java,又遇到了.这里再用Java分析一下对象的转型,并适当利用内存分析来加深理解. 向上转型 我们都知道,狗是动物中的一种,那么如果现在有一个Dog类和Animal类,那么他们的关系就是Dog类继承Animal类. 我们经常说,狗是动物,实际上"狗是动物"这句话就是向上转型的一个例子,即把狗(子类)当做动物(父类)来看待.用一句话来总结,向上转型就是父类的引用指向子类的实例. 实例说明&&内存分析 下面就用一个

关于在cocos2dx中继承Sprite的分析与技巧

本文章特指使用C++作为编程语言,基于cocos2dx游戏引擎开发游戏. 在cocos2dx中,sprite作为精灵类是使用最为频繁的类,与其它类相比,如:Node, Layer或Scene,Sprite最大的不同是它包含一个纹理,通过OpenGL的渲染,在游戏中呈现出来.游戏中的主角,怪物,背景,或是精灵的血条等都是通过Sprite来实现的. 在cocos2dx中,关于创建Sprite的类,根据输入参数的不同有以下几个工厂函数, static Sprite* create() static S

虚继承之单继承的内存布局(VC在编译时会把vfptr放到类的头部,这和Delphi完全一致)

C++2.0以后全面支持虚函数与虚继承,这两个特性的引入为C++增强了不少功能,也引入了不少烦恼.虚函数与虚继承有哪些特性,今天就不记录了,如果能搞了解一下编译器是如何实现虚函数和虚继承,它们在类的内存空间中又是如何布局的,却可以对C++的了解深入不少.这段时间花了一些时间了解这些玩意,搞得偶都,不过总算有些收获,嘿嘿. 先看一段代码class A{      virtual aa(){};}; class B : public virtual  A{      char j[3];      

关于java内存分析的探讨

这些天一直都想找个机会把Java内存方面的知识整理整理,毕竟任何知识都涉及到这方面.Java内存分析是java学习的一大重点. 下面我们进入正式话题讨论: 我们知道Java内存大致分为三块:如下图 我们先大致了解下java各分区的数据存放内容: 栈区:主要为方法服务,存在许许多多的方法栈帧,在方法栈帧里开辟局部变量开辟空间,基本类型按基本数据类型数据大小开辟空间,而引用类型则开辟四个字节大小. 堆区:主要存放创建的对象数据. 方法区:主要存放加载的类,静态变量,静态初始化块,常量,以及程序运行的

python的内存分析和处理

这篇文章写得太好了,记录一下: 引自:https://www.jianshu.com/p/2f98dd213f04 2.内存分析和处理 程序的运行离不开对内存的操作,一个软件要运行,须将数据加载到内存中,通过CPU进行内存数据的读写,完 成数据的运算. 2.1 程序内存浅析 软件的程序在计算机中的执行,主要是通过数据单元.控制单元.执行单元共同协作,完成数据的交互达到程序处理数据的目的,在软件的执行过程中,由于系统内存和CPU的资源有限,所以有效的分解软件中的各项数据,将不同的数据加载到不同的内