Java类是如何默认继承Object的

前言

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

原文地址:https://www.cnblogs.com/andy-alone/p/10773630.html

时间: 2024-10-08 14:06:30

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

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

一.类和对象 1.类 类是数据以及对数据的一组操作的封装体. 类声明的格式: 类声明 { 成员变量的声明: 成员方法的声明及实现: } 1.1 声明类 [修饰符] class 类<泛型> [extends 父类] [implements 接口列表] <泛型>——类的参数,带有参数的类成为泛型类. 1.2 声明成员变量和成员方法 成员变量声明格式:[修饰符] 数据类型 变量[=表达式]{,变量[=表达式]}: 成员方法——用来描述对成员变量进行的操作,格式:[修饰符] 返回值类型 方

初学Java——类和方法(2)继承

1.继承可以使你定义一个通用的类(父类),之后扩充该类为一个更加特定的类(子类).  子类从父类中继承可访问的数据域和方法,还可以添加新的数据域和新方法.  语法:public class Subclass extends Superclass;2.父类中的私有数据域在该类之外是不可访问的,故不能在子类中直接使用,若父类中定义了公共的访问器/修改器,那么可以通过这种方式来访问它们.3.Java不允许多重继承,一个Java类只能直接继承自一个父类(单一继承 simple inheritance),

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

java中提供类与类之间提供单继承. 提供多继承会可能出现错误,如:一个类继承了两个父类,而两个父类里面都有show()方法. class Fulei1{ public void show(){ System.out.println("父类1"); } } class Fulei2{ public void show(){ System.out.println("父类2"); } } class Zilei extends fulei1,fulei2{ public

Java——类、对象与继承

今天我们谈的是――类与对象.类的继承. 2019-08-25 17:22:35 目录怎样定义类,对象又是什么?类在Java中有什么存在的意义?继承在Java中有何重要意义?继承了什么? 类.对象 要理解类的定义,我们首先来了解一下对象是什么.所谓对象,就是现实生活中真真实实存在的事物,例如这个鼠标,这个学生,这个茶杯等等…而类就是对这些真实存在的事物进行一个抽象.我们把具有相同特征的一些对象抽象成为同一个复本,那么这个复本就叫作类.类具有这些对象的相同特征.例如学生这个类(因为不是特指,所以是类

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

一个变量作为类成员使用的时候,如果没有被初始化,java会为其分配默认值: ----------------------------------------------------------------------------------------- Boolean false Char '\u0000'(null) byte (byte)0 short (short)0 int 0 long 0L float 0.0f double 0.0d -----------------------

第9章 Java类的三大特性之一:继承

1.什么是继承 子类继承父类就是对父类的扩展,继承时会自动拥有父类所拥有的处private之外的所有成员作用:增加代码复用语法格式: class 子类名 extends 父类名{----}第9章 Java类的三大特性之一:继承例子: 1 //测试类,创建子类对象,可以直接调用属性和方法 2 public class testDog { 3 public static void main(String[] args) { 4 Dog dog = new Dog(); 5 dog.age=10; 6

Python中新式类 经典类的区别(即类是否继承object)

首先什么是新式类 经典类呢: #新式类是指继承object的类 class A(obect): ........... #经典类是指没有继承object的类 class A: ........... Python中推荐大家使用新式类 1.新的肯定好哈,已经兼容经典类 2.修复了经典类中多继承出现的bug 下面我们着重说一下多继承的bug 如图: BC 为A的子类, D为BC的子类 ,A中有save方法,C对其进行了重写 在经典类中 调用D的save方法 搜索按深度优先 路径B-A-C, 执行的为

Java 类反射机制分析

一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某种机制来实现对自己行为的描述和检测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 在Java中的反射机制,被称为Reflection.(大家看到这个单词,第一个想法应该就是去开发文档中搜一下了.)它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法.Reflection机制

Java从零开始学十五(继承)

一.继承作用 继承使用复用以前的代码非常容易,能够大大的缩短开发周期,降低开发成本,同时增加程序的易维护性 继承使重一个类A能够直接使用另外一个类B的属性和方法的一种途径 类A可以有自己的属性和方法 二.继承实现 类的继承格式 在Java中使用extends关键字完成类的继承关系,操作格式: class 父类{} // 定义父类 class 子类 extends 父类{} // 使用extends关键字实现继承 package com.pb.person; /* * 父类 */ public c