Java如何强制类扩展Object?

时间:2019-03-06 23:00:47

标签: java object inheritance java-native-interface bytecode

内部如何发生?使用什么机制? JNI,反思还是别的什么?编译器是否包括extends子句?

2 个答案:

答案 0 :(得分:0)

不完全正确。

所有类都扩展对象(如果它们还没有扩展另一类的话)有一个例外java.lang.Object本身不会扩展任何类。

如果代码未指定另一个超类,则编译器会将超类java.lang.Object嵌入类文件中。

如果使用您喜欢的编辑器打开.class文件,您甚至可以自己查看它,您可以看到嵌入在二进制数据中的字符串java/lang/Object

(您可以编译一个非常简单的源文件,例如public class A { },以达到最佳效果)

答案 1 :(得分:-1)

这是一个有关Java编译器内部的有趣问题。我找到了一系列文档,它们提供了javac [1] [2] [3] [4]的高级视图。像OpenJdk这样的特定实现的源代码也可以在线[source]找到。

编译包括3个高级步骤[5]

  1. “解析并输入”
  2. “注释处理”
  3. “分析并生成”

我编写了一些代码,以使用提供与javac的接口的编译器树API来测试这些步骤。

static class TestFileObject extends SimpleJavaFileObject {
    public TestFileObject() {
        super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE);
    }
    public CharSequence getCharContent(boolean ignoreEncodingErrors) {
        return "class Test { private int x; }";
    }
}

public static void main(String[] args) throws IOException {
    JavacTool tool = JavacTool.create();
    JavacTask task = tool.getTask(null, null, null, null, null,
            com.sun.tools.javac.util.List.of(new TestFileObject()));

    // Step 1, Parse
    Iterator<? extends CompilationUnitTree> trees = task.parse().iterator();

    // Step 3, Analyze
    // Iterator<? extends Element> elements = task.analyze().iterator();

    // Step 3, Generate
    // Iterator<? extends JavaFileObject> files = task.generate().iterator();

    while(trees.hasNext()) {
        CompilationUnitTree cu = trees.next();
        System.out.println(cu.getTypeDecls());
    }
}

在步骤1中运行上述代码将显示以下输出:

class Test {
    private int x;
}

因此AST不包含对java.lang.Object的引用。接下来,我取消对“ Step 3,Analyse”的注释,并使用结果输出重新运行我的代码:

class Test {

    Test() {
        super();
    }
    private int x;
}

请注意,在此步骤中添加了Test()构造函数和super(), 这也对应于步骤3 [5]的解释:

  

在分析树时,可能会找到成功编译所需的类,但未明确指定要编译的类的引用。

最后,我取消对Step 3, Generate的注释,该文件创建了Test.class文件。调用javap -c Test.class,得到的字节码很暗:

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

所以我的结论是字节码生成步骤添加了java.lang.Object相关的逻辑。