编译.java文件时javac.exe做了什么?

时间:2015-01-29 08:00:58

标签: java compilation jvm javac bytecode

在我看来,javac.exe的作用如下:

  

.java-> blackbox->的.class

我正在尝试阅读openJDK,但我不太了解黑盒子如何工作的过程。所以,我想首先分析一些例子然后再深入openJDK。

E.g:

  public class Choices {
  static class C {}
  static class Java{}

    public static class Tom {
      public void hardChoice(C c) {
        System.out.println("Tom choose c");
      }
      public void hardChoice(Java java) {
        System.out.println("Tom choose java");
      }
    }

    public static class Tommy extends Tom {
      public void hardChoice(C c) {
        System.out.println("Tommy choose c");
      }
      public void hardChoice(Java java) {
        System.out.println("Tommy choose java");
      }
    }

    public static void main(String[] args) {
      Tom tom = new Tom();
      Tom tommy = new Tommy();
      tom.hardChoice(new C());       // mark1
      tommy.hardChoice(new Java());  // mark2
    }
  }

当我将上面的代码放到javac.exe中时,与mark1和mark2对应,我将得到两个带有参数的invokevirtual操作码,字节码为 方法选择$ Tom.hardChoice :( LChoice $ C;)V 方法选择$ Tom.hardChoice :( LChoice $ java;)V

  

问: 进程 将是两行( java中的mark1和mark2   代码 )将成为 两个invokevirtual 方法   和一些相关的字节码。

2 个答案:

答案 0 :(得分:2)

我主要是一名C ++程序员,但出于好奇,我查看了Java的字节码。以下是我们在C ++中的工作:

http://faculty.cs.niu.edu/~mcmahon/CS241/Images/compile.png

这就是Java中发生的事情:

enter image description here

虽然我不是真正的Java程序员,但似乎将java编译成.class代码的工作方式与C或C ++非常相似。 Java将您的代码编译为 Java字节码,这类似于通用程序集指令,可以轻松解释或进一步编译到特定于机器的处理指令中

换句话说,javac.exe将您的代码编译成一种“通用机器代码”,以后可以将其转换为许多不同的,特定类型的机器代码,这些代码仅适用于某些类型的处理器。这就是Java如此多样化的原因 - 它的标准字节码允许有人创建一个“翻译器/解析器”来将Java字节码转换成他们自己机器的特殊机器指令。

答案 1 :(得分:2)

Javac首先解析并检查程序。假设这些步骤通过,程序是有效的,并且将具有Java字节码的表示。 Javac生成这些字节码。基本上ifs和循环转换为使用跳转;由于Java字节码具有操作数堆栈表达式的翻译非常直接。字节码是汇编代码的一种形式,除了它们不是为了匹配任何真实的机器。从那时起,就构建了执行Java字节码的真实硬件。

在Java范例中,虚拟机应该完成所有代码优化,因此大多数javac实现都不执行代码优化。