前言

学过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类了,这是因为编辑器为我们做了一些智能处理。

Java类是如何默认继承Object的的更多相关文章

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

    原:https://juejin.im/post/5ca1e8ade51d454e6a300048 前言 学过Java的人都知道,Object是所有类的父类.但是你有没有这样的疑问,我并没有写exte ...

  2. Java—类的封装、继承与多态

    一.类和对象 1.类 类是数据以及对数据的一组操作的封装体. 类声明的格式: 类声明 { 成员变量的声明: 成员方法的声明及实现: } 1.1 声明类 [修饰符] class 类<泛型> ...

  3. java类为什么是单继承。类的继承,实现接口。

    java中提供类与类之间提供单继承. 提供多继承会可能出现错误,如:一个类继承了两个父类,而两个父类里面都有show()方法. class Fulei1{ public void show(){ Sy ...

  4. 学习笔记 Java类的封装、继承和多态 2014.7.10

    1.问题:toString()没搞懂? int a = 1; Integer aa = new Integer(a); //这是实现的过程 System.out.println("Hello ...

  5. java类的封装、继承、多态

    一.封装(encapsulation) 封装性就是把类(对象)的属性和行为结合成一个独立的相同单位,并尽可能隐蔽类(对象)的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系.封装的特 ...

  6. java 中的interface是否继承object

    首先我们从C++说起, c++可以多继承.也就是一个类型 --- class,可以继承自2个以上的父类型.多继承导致一个问题,很多人知道.例如,如果类型B,类型C均继承自类型A.然后类型D继承自类型B ...

  7. JAVA类与对象(七)------继承

    理解:继承可以理解为一个对象获取属性的过程.如果类A是类B的父类,而类B是类C的父类,我们也称C是A的子类,类C是从类A继承而来.    在java中,类的继承是单一继承,也就是说,一个子类只能拥有一 ...

  8. 【转】Java类成员变量默认初始化规则

    一个变量作为类成员使用的时候,如果没有被初始化,java会为其分配默认值: -------------------------------------------------------------- ...

  9. java类成员的默认可访问性是什么?你猜

    先看下面TestModel: import org.apache.commons.collections4.BidiMap; import org.apache.commons.collections ...

随机推荐

  1. ArcGis使用字段别名Alias Name导出Excel

    在ArcMap10.3+(根据官网描述应该是,作者测试使用10.5,可行)以后的版本,可以使用ArcToolbox工具导出Excel. 工具位置ConversionTools——Excel——Tabl ...

  2. XML配置spring session jdbc实现session共享

    概述 session的基础知识就不再多说. 通常,我们会把一个项目部署到多个tomcat上,通过nginx进行负载均衡,提高系统的并发性.此时,就会存在一个问题.假如用户第一次访问tomcat1,并登 ...

  3. Mysql 根据一个表数据更新另外一个表

    方法一: update 更新表 set 字段 = (select 参考数据 from 参考表 where  参考表.id = 更新表.id); update table_2 m set m.colum ...

  4. [笔记]JS flat and flatMap

    原文 flat()接收一个数组(这个数组中的某些item本身也是一个数组),返回一个新的一维数组(如果没有特别指定depth参数的话返回一维数组). const nestedArraysOhMy = ...

  5. 如何识别Studio 5000程序开发版本号

    前言:中.大型AB PLC的编程软件从以前的RSLogix 5000到目前的Studio 5000,都是有版本号的,如RSLogix 5000 V19.0.Studio 5000 V32.高版本的软件 ...

  6. 【1】学习C++时,一些零散知识点01

    1.编程理念 学习从学习完C后,接触了C++,最重要的便是编程理念的转变.C缩重视的是结构化编程,面对一个较大的程序,就将他分解成小型.便于管理的任务,如果分解后的任务还是偏难过大的话,那将这个任务继 ...

  7. Nodejs一键实现微信内打开网页url自动跳转外部浏览器访问的功能

    前言 现如今微信对第三方推广链接的审核是越来越严格了,域名在微信中分享转发经常会被拦截,一旦被拦截用户就只能复制链接手动打开浏览器粘贴才能访问,要不然就是换个域名再推,周而复始.无论是哪一种情况都会面 ...

  8. 不同IDE对maven项目静态资源处理

    今天自己构建maven管理的web项目,参照另一位兄弟的代码,发现他的静态资源,也就是html.js之类的文件是在src/main/resource目录下的,我的在src/main/resource目 ...

  9. sonar服务搭建

    1.下载安装包,我安装的是6.7.6版本 https://www.sonarqube.org/downloads/ 2.安装前的环境要求 JDK1.8+   数据库,我用的是Mysql5.6版本 3. ...

  10. opencv基础教程 之 图像基础和绘图

    1,教程:感谢小强 2,用argparse传参数来显示一张图片 #!/usr/bin/python #linux系统 #coding=utf-8 import cv2 import argparse ...