gpt4 book ai didi

java - 扩展对象隐式

转载 作者:行者123 更新时间:2023-12-02 01:13:41 29 4
gpt4 key购买 nike

每个人都知道Object是父类(super class),所有不扩展任何其他类的类都会隐式扩展Object类。我想知道这个隐式扩展是如何工作的。

最佳答案

我们有一个文件 child.java

class Child
{
public static void main(String[] args)
{
System.out.println(new Child().toString());
}
}

从上面的代码我们可以看到,其实Child类的父类是Object,所以我们可以在Child中使用Object类的public或者protected资源,比如toString方法。那么Java编译器和JVM是如何做到的呢?

知道这个原因并不需要真正了解JVM的实现细节。想想这个虚拟机程序的原理就知道了。一般来说,对于这类运行在虚拟机上的语言(例如Java),有两种方法可以处理默认继承问题。

  1. 在编译源代码阶段,如果遇到没有父类的类,编译器会给它分配一个默认的父类(通常是Object),而如果虚拟机处理该类,因为该类已经有默认的父类,因此VM仍将以通常的方式处理每个类。在这种情况下,从编译的二进制角度来看,所有类都将有一个父类。

  2. 编译器仍然使用实际代码进行编译,不会进行额外的处理。如果一个类没有显式继承其他类,并且编译后的代码仍然没有父类。那么当虚拟机运行二进制代码时,如果遇到没有父类的类,则自动将该类视为Object类的子类(一般默认父类是Object)。

    <

从上面两种情况可以看出,第一种情况是一篇关于编译器的文章,即当没有父类时,编译器在编译时自动为其分配一个父类。第二种情况是在虚拟机上做文章,即默认的父类是虚拟机添加的。

那么Java又是哪种情况呢?事实上,我们可以通过使用javap来得到这个答案。只要找一个反编译工具,反编译.class文件,看看编译器是如何编译的。以上面的代码为例。如果是第一种情况,即使Child没有父类,因为编译器自动给Child添加了一个Object父类,但是反编译后得到的源码中的Child类是继承自Object类的。如果不是这种情况,则采用第二种情况。

首先将child.java编译为Child.class

%javac child.java

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

 % javap -c Child

在命令之后,我们的字节码以某种可读的形式出现,我们可以在其中识别我们的方法、整数、命令和字符串

class Child {
Child();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class Child
6: dup
7: invokespecial #4 // Method "<init>":()V
10: invokevirtual #5 // Method java/lang/Object.toString:()Ljava/lang/String;
13: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return
}

从上面这段代码可以看出,Test继承自Object,因此可以得出Java是属性的第一种情况,即编译器指定Object为其默认父类没有父类的类。

关于java - 扩展对象隐式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58990173/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com