Java代码编译

作者: 5fafe9a996b9 | 来源:发表于2019-04-17 11:27 被阅读5次

什么是编译

编译是利用编译程序从源语言编写的源程序产生目标程序的过程,一般是指把用高级程序设计语言书写的源程序,翻译成等价的机器语言格式目标程序的翻译程序的过程。完成编译过程的工具就是编译器。

编译过程

java中代码编译是由Javac编译器来完成;
Javac编译器将Java源文件(.java文件)编译成字节码文件(.class文件,是特殊的二进制文件,二进制字节码文件)
编译过程步骤如下 :

image
具体每一步的作用就属于编译原理范畴了。
  • 词法分析:读取源代码,一个字节一个字节的读进来,找出这些词法中我们定义的语言关键词如:if、else、while等,识别哪些if是合法的哪些是不合法的,结果是产生Token流。
  • 语法分析:就是对词法分析中得到的token流进行语法分析,这一步就是检查这些关键词组合在一起是不是符合Java语言规范。如if的后面是不是紧跟着一个布尔型判断表达式,结果是产生抽象语法树。
  • 语义分析:语法分析完成之后也就不存在语法问题了,语义分析的主要工作就是把一些难懂的,复杂的语法转化成更简单的语法。就如难懂的文言文转化为大家都懂的百话文,或者是注释一下一些不懂的成语。
  • 字节码生成:将会根据经过注释的抽象语法树生成字节码,也就是将一个数据结构转化为另外一个数据结构。就像将所有的中文词语翻译成英文单词后按照英文语法组装文英文语句。代码生成器的结果就是生成符合java虚拟机规范的字节码。

javac命令

语法:

javac [ options ] [ sourcefiles ] [ @files ]

options
命令行选项。
sourcefiles
一个或多个要编译的源文件(比如 MyClass.java)。
@files
一个或多个对源文件进行列表的文件。

常用选项

  • -classpath(-cp)指定你依赖的类的class文件的查找位置。在Linux中,用“:”分隔classpath,而在windows中,用“;”分隔。

编译时指定了classpath,在运行的时候注意也可能需要classpath指定依赖的class文件,比如java -cp ../ttdir/:../classes Test,依赖的class文件放在ttdir文件夹中,Test.class放在classes文件夹中(classpath中也要说明需要运行的类的位置)

  • -sourcepath指定你依赖的类的java文件的查找位置。
  • -d指定单独的类文件目标位置

javap命令

可以查看java编译器生成的字节码.class文件或者进行反汇编。
语法:

javap [ options ] [ file ] 

例子

有一个类Test.java

public class Test {
    int x=1;
    static int z=3;
    public static void main(String[] args) {
        int y=2;
        System.out.printf("Hello world \n"+z+y);
    }
}

编译得到Test.class

执行:

$ javap -c Test.class

结果:

Compiled from "Test.java"
public class Test {
  int x;

  static int z;

  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iconst_1
       6: putfield      #2                  // Field x:I
       9: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_2
       1: istore_1
       2: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       5: new           #4                  // class java/lang/StringBuilder
       8: dup
       9: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
      12: ldc           #6                  // String Hello world \n
      14: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      17: getstatic     #8                  // Field z:I
      20: invokevirtual #9                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      23: iload_1
      24: invokevirtual #9                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      27: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      30: iconst_0
      31: anewarray     #11                 // class java/lang/Object
      34: invokevirtual #12                 // Method java/io/PrintStream.printf:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
      37: pop
      38: return

  static {};
    Code:
       0: iconst_3
       1: putstatic     #8                  // Field z:I
       4: return
}

相关文章

  • Java代码编译和执行过程

    Java代码编译和执行过程 Java代码的编译和执行的整个过程大概是:开发人员编写Java代码(.java文件),...

  • JAVA 基础知识(一)

    1.Java代码运行原理 源代码文件(.java)——>java编译器(javac.exe)编译——>字节码文件(...

  • JVM内存模型与数据结构

    JAVA代码执行过程 JAVA源码编译由三个过程组成:源码编译机制、类加载机制、类执行机制。代码编译由JAVA源码...

  • java编译过程

    1、java编译过程与c/c++编译过程不同java编译程序将java源程序编译成jvm可执行代码--java字节...

  • '深入理解Java虚拟机'2018-04-18

    Java代码编译时期是将Java文件编译为Class文件。Java代码执行时期: 装载 JVM通过类的全限定名获取...

  • protobuffer

    源文件:xx.proto 编译器protoc可以编译成c++, java, python代码 java代码 pro...

  • Android加固技术分析与多渠道打包实践

    摘要 由于android应用程序使用java代码开发,java编译生成的.dex文件或.class代码反编译之后很...

  • APK 编译打包 笔记

    一图流 1.Java编译器对工程本身的java代码进行编译,这些java代码有三个来源:app的源代码,由资源文件...

  • java入门笔记

    1、①javac MyFirstJavaProgram.java编译代码;②java MyFirstJavaPro...

  • Java内存模型

    Java程序执行流程 首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀...

网友评论

    本文标题:Java代码编译

    本文链接:https://www.haomeiwen.com/subject/ymvgwqtx.html