`
seara
  • 浏览: 654832 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java.lang.Object是如何成为默认父类的

阅读更多
本文为原创,如需转载,请注明作者和出处,谢谢!

经常有
Java初学者会问为什么一个没有父类的Java类会自动从java.lang.Object类继承。如下面是一个普通的Java类:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassTest//从Object类继承
{
publicstaticvoidmain(String[]args)
{
System.out.println(
newTest().toString());
}
}

从上面的代码可以看出,实际上,Test类的父类就是Object,因此,在Test中可以使用Object类的publicprotected资源,如toString方法。那么Java编译器和JVM到底是如何做的呢?

了解这个原因其实并不需要知道JVM的实现细节。只要思考一下对于这种虚拟机程序的原理即可。一般对于这种靠虚拟机运行的语言(如JavaC#等)会有两种方法处理默认继承问题。

1.在编译源代码时,当遇到没有父类的类时,编译器会将其指定一个默认的父类(一般为Object),而虚拟机在处理到这个类时,由于这个类已经有一个默认的父类了,因此,VM仍然会按着常规的方法来处理每一个类。对于这种情况,从编译后的二进制角度来看,所有的类都会有一个父类。

2.编译器仍然按着实际代码进行编译,并不会做额外的处理。如果一个类没有显式地继承于其他的类,编译后的代码仍然没有父类。然后由虚拟机运行二进制代码时,当遇到没有父类的类时,就会自动将这个类看成是Object类的子类(一般这类语言的默认父类都是Object)。

从上面两种情况可以看出,第1种情况是在编译器上做的文章,也就是说,当没有父类时,由编译器在编译时自动为其指定一个父类。第2种情况是在虚拟机上做文章,也就是这个默认的父类是由虚拟机来添加的。那么Java是属性哪一种情况呢?其实这个答案很好得出。只需要随便找一个反编译工具,并.class文件进行反编译即可得知编译器是如何编译的。就以上面代码为例,如果是第1种情况,就算Test没有父类,但由于编译器已经为Test自动添加了一个Object父类,因此,在反编译后得到的源代码中的Test类是从Object类继承的。如果没是这种情况,那么就是第2种情况。

现在我们使用JDK带的反编译工具javap来反编译Test.class,先执行下面的命令:

javap Test > Test.txt

打开Test.txt文件后,会看到如下的代码:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassTestextendsjava.lang.Object{
publicTest();
publicstaticvoidmain(java.lang.String[]);
}

再使用下面的命令来得到bytecode代码:

javap -c Test >Test1.txt

打开Test1.txt后,会看到如下的代码:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassTestextendsjava.lang.Object{
publicTest();
Code:
0:aload_0
1:invokespecial#8;//Methodjava/lang/Object."<init>":()V
4:return

publicstaticvoidmain(java.lang.String[]);
Code:
0:getstatic#16;//Fieldjava/lang/System.out:Ljava/io/PrintStream;
3:new#1;//classTest
6:dup
7:invokespecial#22;//Method"<init>":()V
10:invokevirtual#23;//Methodjava/lang/Object.toString:()Ljava/lang/String;
13:invokevirtual#27;//Methodjava/io/PrintStream.println:(Ljava/lang/String;)V
16:return
}

从上面两段代码可以看出,Test已经从Object继承了,因此,可以断定Java是属性第1种情况,也就是说由编译器为没有父类的类指定了Object作为其默认父类。如果读者还不确定,可以直接打开Test.class,看看里面有没有Object,图1Test.class的十六进制代码:



图1

大家可以看到,Java编译器已经为Test指定了一个默认的Object类作为其父类。目前大多数基于虚拟器的语言都是采用的第1种方法来处理默认父类的,如下面的C#代码:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->usingSystem;

namespaceConsoleApplication1
{
classTest
{
staticvoidMain(string[]args)
{
Console.WriteLine(
newTest().ToString());
}
}
}

使用ildasm.exe将上面的代码反编译后,得到的MSIL代码如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->.classprivateautoansibeforefieldinitConsoleApplication1.Test
extends[mscorlib]System.Object
{
}
//endofclassConsoleApplication1.Test

从上面的代码可以清楚地看到,Test类已经有一个System.Object作为父类了。




国内最棒的Google Android技术社区(eoeandroid),欢迎访问!

《银河系列原创教程》发布

《Java Web开发速学宝典》出版,欢迎定购

分享到:
评论

相关推荐

    java源码阅读之java.lang.Object

    Java中的Object类是所有类的父类,任何类都默认继承Object。Object类提供了多种方法,以下是其中一些重要的方法: 1. clone方法:保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出...

    javaapi.zip

    `java.lang` 包含了所有 Java 程序都默认导入的基本类,如 `Object`、`String` 和 `System`。`java.util` 提供了集合框架、日期时间、随机数生成等工具类。`java.io` 包则涉及输入输出操作,如文件读写、流处理等。 ...

    java语言程序设计试题

    这意味着即使是用户自定义的类,如果没有明确指定父类,也会默认继承自`Object`类。 **3. 基本数据类型的封装类** Java提供了对基本数据类型的封装类,这些类位于`java.lang`包中。对于每个基本数据类型都有一个...

    Java SDK源代码

    `java.lang` 包含了所有Java程序都默认导入的基本类,如`Object`, `String`, `System`等。`java.util` 提供了各种实用工具类,如集合框架、日期时间处理、随机数生成等。`java.io` 和 `java.nio` 用于输入输出操作,...

    语言程序设计资料:JAVA期末考试试卷.doc

    6. `java.lang.Object`的重要性:`java.lang.Object`是Java所有类的根类,任何自定义类如果没有指定父类,那么默认继承自`Object`。 7. Swing事件处理机制:Swing的事件处理机制基于监听器模式,包括事件的监听者...

    Java学习IO流小结--字符流

    - `java.io.FileReader` → `java.io.Reader` → `java.lang.Object` - `java.io.FileWriter` → `java.io.Writer` → `java.lang.Object` - **构造方法**: - `FileReader(String fileName)`:创建一个`...

    Java Object类认识

    在Java编程语言中,`Object`类是所有类的根,每个自定义类如果没有明确指定父类,都默认继承自`Object`。因此,对`Object`类的理解是每个Java开发者的基本功。本文将深入探讨`Object`类,以及其核心方法`equals()`与...

    java反射获取所有属性,获取所有get方法,包括子类父类

    在Java中,`java.lang.Class` 类提供了获取类属性的方法。要获取类的所有属性(包括public、private、protected以及默认访问权限的属性),可以使用以下代码: ```java Class&lt;?&gt; clazz = Class.forName("全限定...

    JAVA+API官方文档中文版

    1. **基础类库**:Java API的基础类库包括`java.lang`包,其中包含了所有Java程序都默认导入的基本类,如`String`、`Object`、`System`等。`Object`类是所有类的父类,提供了`equals()`、`hashCode()`和`toString()`...

    4.反射-introdute.doc

    1. **Class类**:`java.lang.Class`是Java反射的基础,它代表了Java中的每一个类或接口。通过`Class`对象,我们可以获取到类的各种信息,如类名、构造器、方法、字段等。 2. **获取Class对象**: - `Class.forName...

    J2EE面试题集锦(附答案)

    `java.lang.Number` 是一个抽象类,用于表示数值类型的基本封装类的父类。 - **`java.lang.Double`:** 错误。`java.lang.Double` 实际上是一个类,用于包装 `double` 类型的原始数据。 - **`java.lang.Math`:** 错误...

    Java-SE-class-library-.zip_java se

    1. **Java基础类库**:Java的基础类库包括`java.lang`包,它是所有Java程序的默认导入包,包含如`String`, `Object`, `System`等核心类。`String`类用于处理文本字符串,`Object`是所有Java类的父类,`System`类提供...

    Java SE API中文版

    首先,Java SE API的核心在于Java语言的核心类库,包括`java.lang`包,它是每个Java程序的默认导入包,包含了如`String`、`Object`、`System`等基础类。`Object`类是所有类的父类,提供了`equals()`和`hashCode()`等...

    面向对象程序设计Java.ppt

    面向对象程序设计(Object-Oriented Programming,OOP)是现代软件开发中广泛采用的一种编程范式,尤其在Java语言中得到了深入的应用。本资源"面向对象程序设计Java.ppt"是一个基础讲解材料,旨在帮助初学者理解并...

    java动态代理

    Java代理机制主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。通过实现`InvocationHandler`接口并利用`Proxy.newProxyInstance()`方法可以创建一个动态代理对象。该对象能够...

    java各类帮助文档

    1. **基础类库**:Java API的基础类库包括`java.lang`包,它是所有Java程序的默认导入包,包含如`String`、`Integer`、`Object`等核心类。`Object`是所有类的父类,提供了诸如`equals()`、`hashCode()`和`toString()...

    推选文档Java-程序设计PPT.ppt

    所有Java程序默认导入此包,因此无需显式导入`java.lang`中的类。`Object`类是所有类的父类,它提供了诸如`equals()`、`hashCode()`、`toString()`等基本方法。`equals()`方法用于比较两个对象是否相等,通常需要...

    Java类库-适合初学者学习Java编程语言

    1. **基础类库**:Java的基础类库包括了`java.lang`包,它是所有Java程序的默认导入包,包含了诸如`String`、`Integer`、`Object`等基本类型和对象。`String`类用于处理文本字符串,而`Object`类是所有Java类的父类...

    Java语言程序设计教程-雷学生-电子教案-2041

    作为Java程序的默认导入包,java.lang包含了所有Java程序都需要的基本类。其中的`Object`类是所有Java类的根类,提供了诸如`equals()`、`hashCode()`和`toString()`等通用方法。此外,还有基本类型的包装类,如`Byte...

    Java 60 道面试题及答案.docx

    Object 类是 Java 中的顶级父类,所有的 Java 类都是 Object 类的子类。 4. Object 类常用方法有哪些?Object 类常用方法有 equals、hashCode、toString、wait、notify、clone、getClass 等。 5. Java 中有没有...

Global site tag (gtag.js) - Google Analytics