【问题标题】:Classes not extending java.lang.Object不扩展 java.lang.Object 的类
【发布时间】:2009-08-28 04:39:12
【问题描述】:

当您在 Java 中创建用户定义的类时,您没有将其指定为扩展 Object。但是这个类仍然是一个对象。这是如何运作的? javac或JVM如何将一个类的所有属性注入到用户定义的类中?

【问题讨论】:

    标签: java inheritance compiler-construction


    【解决方案1】:

    如果你实际上没有写extends Object,编译器会为你插入它。

    编辑:显然我对是否真的有代码插入造成了一些混乱。我自己不太确定,所以我做了一个小实验:在文件 test.java 中创建以下类:

    public class test {}
    

    编译,然后运行

    javap -c test
    

    反汇编字节码。看看结果:

    编译自“test.java”
    公共类测试扩展 java.lang.Object{
    公共测试();
      代码:
       0:aload_0
       1:调用特殊#1; //方法 java/lang/Object."":()V
       4:返回
    
    }

    所以是的,编译器确实实际上将extends java.lang.Object(或等效的字节码)插入到类中。

    【讨论】:

    • 真正的问题是,如何让人们停止在他们的代码中编写扩展对象
    • @Ken: 用一根大棍子打他们的头:-)。严肃地说,任何半体面的 Java 样式检查器都应该将“扩展对象”标记为可憎。
    • @StephenC 从技术上讲,java/lang/Object 类没有超类。在这种情况下,超类字段设置为 0 而不是常量池条目。
    • 嗯...是的。但是如果我们插入明显的骑手“除了 java.lang.Object”,它会使 cmets 更长。
    【解决方案2】:

    所有 java 类都隐式扩展 java.lang.Object。来自documentation

    Object 是类层次结构的根。每个类都有Object 作为超类。所有对象,包括数组,都实现了这个类的方法。

    这里还有一个指向JVM spec 的链接:

    标准类Object 是所有其他类的超类(第 2.8.3 节)。 Object 类型的变量可以保存对任何对象的引用,无论它是类的实例还是数组。所有类和数组类型都继承了 Object 类的方法。

    【讨论】:

      【解决方案3】:

      嗯,这可能是一个油嘴滑舌的答案(我最喜欢的那种),但如果你指定一个父类,它可能会以同样的方式派生一个类。如果您编写编译器,您不就是这样做的吗?

      【讨论】:

        【解决方案4】:

        这是因为所有用户定义的类型都隐式继承自 Object。

        【讨论】:

          【解决方案5】:

          如果说 JVM 将属性或方法“注入”到类中,这听起来像是编译器或运行时在事后所做的事情,就好像 .class 文件不同一样。实际上,所发生的只是当解析器发现您没有在extends 中包含任何基类时,它只是假装您明确指定了Object。从那时起,编译器将其视为您自己输入的一样,并且 JVM 不知道您在源代码中做了什么或没有指定什么。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-10-07
            • 2015-06-22
            • 1970-01-01
            • 2017-03-28
            • 1970-01-01
            • 1970-01-01
            • 2019-10-28
            • 1970-01-01
            相关资源
            最近更新 更多