java 中关键字 super 表示的真正对象

本贴最后更新于 3212 天前,其中的信息可能已经渤澥桑田

Java 中关键字 super 表示的真正对象
java 中的 super,大家都知道是表示一个父类的引用。上次群里见到一个网友询问 super.getClass().getName()的输出问题,大部分都知道输出的是当前这个类的类名。而不是父类的名称。关于这个问题的解释很多,基本都是说 getClass()是一个 final 方法,说这个方法都是调用超父类 Object 的方法。这个解释很好,也容易理解,不过,我们从 super 这个关键词的本质入手,就能更清楚,为什么 super.getClass().getName()会输出当前类的名称了。

先定义两个类,一个父类,一个继承的子类。

父类:

[java] view plain copy

  1. public class Parent {
  2. public String name;
  3. private int code;
  4. public Parent parent;
  5. //定义几个父类成员属性,parent将指向this父类对象
  6. public Parent()
  7. {
  8. //parent指向this,就是当前实例的父类对象,并输出hashcode和给code属性赋值
  9. parent=this;
  10. code=1001;
  11. System.out.println("Parent's code is:"+code);
  12. System.out.println("Parent hashcode is:"+this.hashCode());
  13. }
  14. //定义一个重载的构造方法,用于测试使用了哪个父类构造方法
  15. public Parent(String name){
  16. parent=this;
  17. this.name=name;
  18. System.out.println("Parent's name is"+name);
  19. code=1002;
  20. System.out.println("Parent's code is"+code);
  21. System.out.println("Parent hashcode is:"+this.hashCode());
  22. }
  23. public int getCode()
  24. {
  25. //打印父类code属性值,
  26. System.out.println("Parent :print code :"+code);
  27. return code;
  28. }
  29. }

子类:

[java] view plain copy

  1. public class Child extends Parent{
  2. public String childName;
  3. private int childCode;
  4. //定义两个类的不同修饰符的属性
  5. public Child(String childName)
  6. {
  7. //给属性赋值
  8. this.childName=childName;
  9. //输出属性值,和类的hashcode值
  10. System.out.println("child's childName is:"+childName);
  11. System.out.println("child hashcode is:"+this.hashCode());
  12. }
  13. //测试方法
  14. public void test()
  15. {
  16. //通过super获取父类中的parent,这个成员就表示了父类对象。
  17. Child testChild=(Child)super.parent;
  18. //强转parent为子类类型。并输出子类中定义的属性,和获取父类getCode()方法
  19. System.out.println("testChild name is:"+testChild.childName);
  20. testChild.getCode();
  21. }
  22. public static void main(String[] args) {
  23. //实例化
  24. Child c=new Child("window");
  25. c.test();
  26. }
  27. }

运行输出结果:

Parent's code is:1001

//首先输出这句,可以表示,父类默认的构造方法执行了。
Parent hashcode is:11985823

//这里输出的父类 this 对象的 hashcode 码

child's childName is:window

//调用子类的构造方法,输出childName和hashcode码值,大家可以看到,父类的this对象和子类实例的对象,hashcode码是相同的。

child hashcode is:11985823

//这里执行test()方法的结果。 //使用Child testChild=(Child)super.parent 强制转换父类中指向父类this对象的parent对象为子类Child对象,并输出子类childName属性值。

testChild name is:window

//输出结果上可以看出,这个parent其实就是子类的实例对象。应该说内存中的对象是同一个,只是不同的表示方式。 //执行testChild.getCode(); 调用父类的getCode()方法,输出的和父类构造方法中的code值是相同的。

Parent :print code :1001

从上面可以看出 super 这个关键字所表示的引用父类对象,其实和当前实例化的子类对象在内存中是同一个对象,虽然不知道 sun 的虚拟机是如何实现这个关键字的,但是这个 super 的等同效果就是(Parent)this,这里的 this 是当前代表当前实例化的子类对象。

通过在父类中添加一个 Parent 类型的成员,来指向父类实例化的那个 this 对象,达到引用父类对象的目的,使用 super.parent 来获得父类 parent 对象的引用。

运行的结果表明,这个 parent 应用的其实就是当前子类实例对象,通过强制转换为子类类型,这个父类 Parent 类型的 parent 也可以读取成员 childName 属性值。就表明了他们在内存中是同一个对象。而且他们的 hashcode 值也是相同的。

java 说明中指出,super 是代表父类对象的引用,而 super()表示应用父类的默认构造方法,看起来这个 super 和 c 中的 define 有点相同作用的效果。在这个例子中,super 代表的父类对象的引用,和父类中 parent 代表的都是父类对象的引用,parent 其实就是当前内存中子类对象的引用,如同(Parent)this 一样,这样就可以解释为什么使用(Child)super.parent 可以得到子类成员 childName。

回到开始的问题,super.getClass().getName(),这样,就很容易解释他为什么是输出当前类的名称了,因为构造一个实例化对象,其中,在父类和子类构造方法中,引用的对象都是同一个,都是当前实例化的子类对象。super 关键字应该充当了一个类型转化的作用。

熟悉 c 的知道,c 中经常使用强制转换指针类型来引用一些结构或变量的部分数据,如通过强制转换为不同结构类型,来引用不同数据大小的结构体。这里的应用效果应该等同,通过(Parent)Child 可以通过转换为父类类型而只引用父类类型的那一部分数据。

在 java 中 new 一个对象,和 c 或 c++ 这些和内存打交道的语言一样,都是会分配内存,在 c 中可能更直观一点,我们在此不讨论到底是分配了多大的内存问题。

在 new 一个子类的时候,上面例子看到,父类的成员同样也有赋值初始化,说明,同样在内存中也有保存父类的信息空间,(Object 类的不讨论)。

  • super
    1 引用 • 1 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3205 引用 • 8217 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 20 关注
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖 • 1 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • Visio
    1 引用 • 2 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 555 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖 • 1 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 671 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 696 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    10 引用 • 15 回帖 • 2 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    108 引用 • 153 回帖
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖 • 1 关注
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 563 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 80 回帖
  • 工具

    子曰:“工欲善其事,必先利其器。”

    305 引用 • 772 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 7 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 691 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 360 关注
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 681 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • OneDrive
    2 引用 • 1 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    39 引用 • 167 回帖 • 3 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    104 引用 • 908 回帖 • 1 关注
  • 分享

    有什么新发现就分享给大家吧!

    249 引用 • 1799 回帖