`
xitong
  • 浏览: 6176985 次
文章分类
社区版块
存档分类
最新评论

Java继承关系、构造器的内存分析

 
阅读更多

由于ZangXT对这个问题提出了质疑, 所以, 在文末, 又追加了一个测试使用super绕过多态的例子, 以期证明, 构造一个对象的时候, 隐含的持有了父类的引用(或者以更合适的名词称呼: 向上代理)

  1. packagetest1;
  2. /**
  3. *
  4. *@authorleslie
  5. */
  6. classMyA{
  7. inta=1;
  8. publicMyA(){
  9. print();
  10. }
  11. publicvoidprint(){
  12. System.out.println("aaa"+a);
  13. }
  14. }
  15. classMyBextendsMyA{
  16. inta=2;
  17. publicMyB(){
  18. print();
  19. }
  20. publicvoidprint(){
  21. System.out.println("bbb"+a);
  22. }
  23. }
  24. classMyCextendsMyB{
  25. inta=3;
  26. publicMyC(){
  27. print();
  28. }
  29. publicvoidprint(){
  30. System.out.println("ccc"+a);
  31. }
  32. }
  33. publicclassMain{
  34. /**
  35. *@paramargsthecommandlinearguments
  36. */
  37. publicstaticvoidmain(String[]args){
  38. newMyC();
  39. }
  40. }
  41. 这个程序在netbean下返回的是:
  42. ccc0
  43. ccc0
  44. ccc3

问题就是上面写的这样,下面是内存分析.

执行new MyC();时候的调用顺序.
1. ClassLoader加载MyC这个类.
2. 准备调用MyC的构造方法.
3. 准备调用MyC的父类MyB的构造方法.
4. 准备调用MyB的父类MyA的构造方法.
5. 准备调用MyA的父类java.lang.Object的构造方法.
6. 执行java.lang.Object的构造方法.
7. 初始化MyA类的成员变量,a=1;
注意:此时堆栈中对象的分布是MyC的对象持有MyB对象的一个引用,MyB对象持有MyA对象的一个引用,MyA对象持有java.lang.Object对象的一个引用,MyA,MyB,MyC对象中各有一个成员变量a,一定注意,这个时候,堆栈中有三个a,此时MyA的成员变量a=1;MyB和MyC的成员变量a=0;
8. 执行MyA的构造方法,调用print方法
注意:这里有多态,我们调用的方法实际上是MyC对象重写的方法,也就是说内存代码区向外提供调用的print方法是MyC的print方法,由于MyC中的成员变量a=0,所以此时打印 "ooo0 ";
9. 初始化MyB的成员变量.和第7条同理,此时堆栈中MyA的a=1,MyB的a=2,MyC的a=0;
10. 执行MyB的构造方法.和8同理,调用的还是MyC的print方法,所以打印的是 "ooo0 ";
11. 初始化MyC的成员变量.和第7条同理,此时堆栈中MyA的a=1,MyB的a=2,MyC的a=3;
12. 执行MyC的构造方法.和8同理,调用的是MyC的print方法,此时MyC的成员变量a=3,所以打印的是 "ooo3 ";

做这个内存分析的时候,主要考虑new MyC();这一句执行的过程:
1. ClassLoader加载MyC;
2. 进入MyC的构造器,首先构造MyC的父类,直到Object,Object之后怎么处理就不清楚了.
3. 处理完父类构造器之后,处理成员变量的初始化.
4. 然后执行构造器中的代码.

相关的东西:
多态:一个类继承关系中的重写的方法,在调用的时候,只有一个,那就是重写了那个方法的备份最小的类中的方法体.

以下是试图证明存在super引用的代码. 感兴趣的朋友可以把子类B中的f()方法中的super.m()换成this.m(), 就能看到区别了.

父类的代码

  1. publicclassA{
  2. publicvoidm(){
  3. System.out.println("ThisisA");
  4. }
  5. }

子类的代码:

  1. publicclassBextendsA{
  2. @Override
  3. publicvoidm(){
  4. System.out.println("ThisisB");
  5. }
  6. publicvoidf(){
  7. super.m();
  8. }
  9. }

测试代码:

  1. publicclassTest{
  2. /**
  3. *@paramargs
  4. */
  5. publicstaticvoidmain(String[]args){
  6. Bb=newB();
  7. b.f();
  8. }
  9. }

转自:http://blog.csdn.net/lgg201/article/details/4061041

分享到:
评论

相关推荐

    Java开发技术大全(500个源代码).

    inheritConstruct_3.java 构造器继承示例3 inheritConstruct_4.java 构造器继承示例4 inheritConstruct_5.java 构造器继承示例5 inheritConstruct_6.java 构造器继承示例6 inheritor.java 子类覆盖父类示例 ...

    java实验报告.docx

    构造器应用 16 实验五 Java访问控制管理;封装类;内部类; 内存管理与垃圾收集 8 实验六 Java 异常处理的程序设计;Java 自定义异常的程序设计 13 实验七 Java 多线程程序设计应用 1 实验八 Java 泛型程序设计应用 ...

    Python-函数和内存分析 2.zip

    ================面向对象和内存分析================== 086.面向对象和面向过程的区别_执行者思维_设计者思维 087.对象的进化故事 088.类的定义_类和对象的关系 089.构造函数__init__ 090.实例属性_内存分析 091....

    Python-面向对象和内存分析 2.zip

    ================面向对象和内存分析================== 086.面向对象和面向过程的区别_执行者思维_设计者思维 087.对象的进化故事 088.类的定义_类和对象的关系 089.构造函数__init__ 090.实例属性_内存分析 091....

    corejava笔记

    3 构造器(构造方法) 的作用: 用来描述对象的创建过程的. 1) 如: 月饼实例的创建, 使用面和馅创建. 制作(构造器) 月饼模子(类) -----> 月饼(对象) 原料(构建参数) 点类型 --------> 原点 坐标(1,2) 5...

    疯狂JAVA讲义

    学生提问:构造器是创建Java对象的途径,是不是说构造器完全负责创建Java对象? 141 5.5.2 构造器的重载 142 学生提问:为什么要用this来调用另一个重载的构造器?我把另一个构造器里的代码复制、粘贴到这个构造器...

    Java开发详解.zip

    031205_【第12章:JAVA IO】_内存操作流笔记.pdf 031206_【第12章:JAVA IO】_管道流笔记.pdf 031207_【第12章:JAVA IO】_打印流笔记.pdf 031208_【第12章:JAVA IO】_System类对IO的支持笔记.pdf 031209_【第12章...

    JAVA基础课程讲义

    构造器(或者叫做构造方法,constructor) 60 垃圾回收机制(Garbage Collection) 63 方法的重载(overload),构造方法的重载 63 this关键字 65 static 关键字 66 静态初始化块(经常用来初始化类,加载类信息时执行!) ...

    Java测试题2答案

    欲构造ArrayList类的一个实例,此类继承了List接口,下列哪个方法是正确的 ? B A ArrayList myList=new Object(); B List myList=new ArrayList(); C ArrayList myList=new List(); D List ...

    Java入门教程(微学苑)-part1

    4 Java继承和多态 61 4.1 继承的概念与实现 61 4.2 Java super关键字 63 4.3 调用隐藏变量和被覆盖的方法 63 4.4 调用父类的构造方法 64 4.5 继承中的方法的覆盖和重载 65 4.6 多态和动态绑定 66 4.7 动态绑定 69 ...

    Java优化编程(第2版)

    展示了如何提升Java应用性能,并且给出了优化前与优化后的Java应用程序的性能差别,以实际的实例与数字告诉你,为什么不可以这么做,应该怎么做,深入分析了影响Java应用程序性能的根本原因。本书不是教你怎样使用...

    JAVA面试题最全集

    方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() ...

    Java面向对象程序设计笔记

    Java编译器、解释器、JVM以及OS之间的关系 4 JVM的结构与作用 4 2. 程序设计的发展过程 4 程序设计的发展过程 4 O-O发展过程 5 O-O的体系 5 O-O程序设计与结构化程序设计的区别 5 3. Java应用程序 5 搭建...

    java 面试题 总结

    但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...

    Java2核心技术.part5

    4.3.4从构造器开始 5.2.2相等测试与继承 5.2.3 hashCode方法 5.2.4 toString方法 5.3泛型数组列表 5.3.1访问数组列表元素 5.3.2类型化与原始数组列表的兼容性 5.4对象包装器与自动打包 5.5...

    AIC的Java课程1-6章

     弄清构造函数和终结方法在继承层次结构中的调用顺序,强调子类必须调用超类的构造函数分配空间和初始化超类数据。  掌握方法重写(override)的基本要求。  理解和使用关键字final。  理解包的...

    【04-面向对象(上)】

    •如果程序员没有Java 类提供任何构造器,则系统会为这个类提供一个无参的构造器。 •一旦程序员提供了自定义的构造器,遇系统不再提供默认的构造器。 构造器的重载 •构造器的重载和方法的重载一样,都...

    Java免费学之画板入门源码和视频

    前言:画板小程序是对之前Java中的类,继承,方法重载以及接口等知识的综合应用; 建议大家先去把相关知识看一下 思路: 1.创建窗体 2.在窗体上安装鼠标监听器,对鼠标动作进行监听; 3.拿到鼠标在窗体上按下...

Global site tag (gtag.js) - Google Analytics