优彩彩票_优彩彩票技巧_优彩彩票计划|首页

登录立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

楼主:littleRed
打印上一主题下一主题

Java类是如何默认继承Object的?

[复制链接]

402

主题

405

帖子

8307

安币

手工艺人

跳转到指定楼层
楼主
发表于 2019-4-4 12:12:13|只看该作者|只看大图回帖奖励|倒序浏览|阅读模式
前言
学过Java的人都知道,Object是所有类的父类。但是你有没有这样的疑问,我并没有写extends Object,它是怎么默认继承Object的呢?
那么今天我们就来看看像Java这种依赖于虚拟机的编程语言是怎样实现默认继承Object的,以及Java编译器和JVM到底是如何做的?
继承自Object验证
首先我们来验证一下Object是不是所有类的父类,随便新建一个Java类,如下图:


从上面的代码可以看出,new MyClass()打点之后可以选择调用的方法有很多,我们定义的MyClass类里面只有一个main方法,那这些方法哪来的,显然是Object里声明的,故MyClass类的父类就是Object,因此,在MyClass中可以使用Object类的public或protected资源。另外,当A类继承MyClass类时,通过打点也可以调到Object内的方法,这是继承的传递,好比Object是MyClass的“父亲”,MyClass是A类的“父亲”,Object是A类的“爷爷”,间接的继承了Object。
因此,Object是超类,是所有类的父类。
推测可能的原因
要了解Java类是如何默认继承Object的?的原因其实并不需要知道JVM的实现细节。只需了解一下对于这种虚拟机程序的基本原理即可。一般对于这种靠虚拟机运行的语言(如Java、C#等)会有两种方法处理默认继承问题。
编译器处理
在编译源代码时,当一个类没有显式标明继承的父类时,编译器会为其指定一个默认的父类(一般为Object),而交给虚拟机处理这个类时,由于这个类已经有一个默认的父类了,因此,VM仍然会按照常规的方法像处理其他类一样来处理这个类。对于这种情况,从编译后的二进制角度来看,所有的类都会有一个父类(后面可以以此依据来验证)。
JVM处理
编译器仍然按照实际代码进行编译,并不会做额外的处理,即如果一个类没有显式地继承于其他类时,编译后的代码仍然没有父类。然后由虚拟机运行二进制代码时,当遇到没有父类的类时,就会自动将这个类看成是Object类的子类(一般这类语言的默认父类都是Object)。
验证结论
从上面两种情况可以看出,第1种情况是在编译器上做的文章,也就是说,当没有父类时,由编译器在编译时自动为其指定一个父类。第2种情况是在虚拟机上做文章,也就是这个默认的父类是由虚拟机来添加的。
那么Java是属于哪一种情况呢?其实这个答案很好得出。只需要随便找一个反编译工具,将.class文件进行反编译即可得知编译器是如何编译的。
就以上面代码为例,如果是第1种情况,就算MyClass没有父类,但由于编译器已经为MyClass自动添加了一个Object父类,所以,在反编译后得到的源代码中的MyClass类将会继承Object类的。如果不是这种情况,那么就是第2种情况。
那么实际情况是什么样的呢?现在我们就将MyClass.class反编译看看到底如何。
jd-gui反编:


使用JDK自带的工具(javap)反编译CMD命令行下执行:javap MyClass>MyClass.txt


可以看出实际的反编译后的文件中并没有extends Object,使用排除法,因此是第2情况。这样来推导出的结论是第2种情况,但事实真的如此吗?为什么网上还有说反编译后的是有extends Object字样?
JDK版本问题?
猜想是JDK版本的问题,于是把JDK版本切换到7,使用jd-gui和javap反编译,接果和使用JDK8反编译后的结果一样,也都没有extends Object。
继续换版本,昨晚在宿舍准备到Oracle官网下载JDK 6,但是死活下不来,今早到公司后第一件事就是下载,很顺利,安装后把JDK版本切换到JDK 6。
仍然在CMD窗口执行javap MyClass>MyClass.txt,得到的TXT文件内容如下:


what?竟然有extends Object,jd-gui反编译后的依然没有。 即,JDK 6之前使用javap反编译后的MyClass类显式的继承Object,JDK 7以后没有;jd-gui反编译后的不管JDK版本如何始终没有。我们以java自带的工具为准。总结
那么就是说JDK 6之前是编译器处理,JDK 7之后是虚拟机处理。
但是仔细想想我们在编辑器里(IDEA)打点时就能列出Object类下的方法,此时还没轮到编译器和jvm,编辑器就已经知道MyClass类的父类是Object类了,这是因为编辑器为我们做了一些智能处理。

回复

举报

400

主题

1034

帖子

350

安币

手工艺人

沙发
发表于 2019-4-4 12:17:48|只看该作者
感谢分享,楼主V5~

0

主题

9455

帖子

2484

安币

Android大神

Rank: 6Rank: 6

板凳
发表于 2019-4-4 12:30:36|只看该作者
安卓巴士是个不错的网站,我来顶个贴~

7

主题

9540

帖子

1979

安币

Android大神

Rank: 6Rank: 6

地板
发表于 2019-4-4 12:41:19|只看该作者
感觉楼主很用心,辛苦啦~

350

主题

924

帖子

793

安币

手工艺人

5#
发表于 2019-4-4 12:41:59|只看该作者
感谢分享,安卓巴士有你更精彩:lol

465

主题

9876

帖子

827

安币

代码手工艺人

Rank: 4

6#
发表于 2019-4-4 12:57:42|只看该作者
楼主是好人,回个帖会有安币吗?

92

主题

9550

帖子

1991

安币

Android大神

Rank: 6Rank: 6

7#
发表于 2019-4-4 13:03:14|只看该作者
支持,感谢,祝巴士越来越好~
高级模式
BColorImageLinkQuoteCodeSmilies
您需要登录后才可以回帖登录|立即注册

本版积分规则

站长推荐

通过邮件订阅最新安卓weekly信息
上一条/4下一条

下载安卓巴士客户端

全国最大的安卓开发者社区
商务合作
商务合作
问题反馈及帮助
联系我们

广告投放|广东互联网违法和不良信息举报中心|中国互联网举报中心|下载客户端|申请友链|手机版|站点统计|安卓巴士(粤ICP备000001号)

快速回复返回顶部返回列表