javac 订阅
javac 是java语言编程编译器。全称java compiler。javac工具读由java语言编写的类和接口的定义,并将它们编译成字节代码的class文件。javac 可以隐式编译一些没有在命令行中提及的源文件。用 -verbose 选项可跟踪自动编译。当编译源文件时,编译器常常需要它还没有识别出的类型的有关信息。对于源文件中使用、扩展或实现的每个类或接口,编译器都需要其类型信息。这包括在源文件中没有明确提及、但通过继承提供信息的类和接口。 展开全文
javac 是java语言编程编译器。全称java compiler。javac工具读由java语言编写的类和接口的定义,并将它们编译成字节代码的class文件。javac 可以隐式编译一些没有在命令行中提及的源文件。用 -verbose 选项可跟踪自动编译。当编译源文件时,编译器常常需要它还没有识别出的类型的有关信息。对于源文件中使用、扩展或实现的每个类或接口,编译器都需要其类型信息。这包括在源文件中没有明确提及、但通过继承提供信息的类和接口。
信息
结    构
javac
options
命令行选项
中文名
javac
@files
多个对源文件进行列表的文件
javac结构
[ options ] [ sourcefiles ] [ @files ]参数可按任意次序排列。命令行选项。一个或多个要编译的源文件(例如 MyClass.java)。
收起全文
精华内容
下载资源
问答
  • javac
    2021-03-05 14:19:34

    javac -d . *.java(注意,-d后面有个空格和点)

    javac:如果当前你要编译的java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加上-classpath参数,通过使用以下三种类型的方法 来指导编译器在编译的时候去指定的路径下查找引用类。

    (1).绝对路径:javac -classpath c:/junit3.8.1/junit.jar   Xxx.java

    (2).相对路径:javac -classpath ../junit3.8.1/Junit.javr  Xxx.java

    (3).系统变量:javac -classpath %CLASSPATH% Xxx.java (注意:%CLASSPATH%表示使用系统变量CLASSPATH的值进行查找,这里假设Junit.jar的路径就包含在CLASSPATH系统变量中)

    (4).如果引用的第三方类在一个.jar 中,则这个时候,javac的时候,必须在classpath中指定到具体的jar。

    同样,对于包下的类,E:/>java -classpath d:/java com.zzq.HelloWorld

    也就是说,必须设定classpath

    以下引用自百度javac的解析

    javac

    [ options ] [ sourcefiles ] [ @files ]

    参数可按任意次序排列。

    options

    命令行选项。

    sourcefiles

    一个或多个要编译的源文件(例如 MyClass.java)。

    @files

    一个或多个对源文件进行列表的文件。

    说明

    两种方法

    javac 工具读取用 Java 编程语言编写的类和接口定义,并将它们编译成字节码类文件。

    有两种方法可将源代码文件名传递给 javac:

    如果源文件数量少,在命令行上列出文件名即可。

    如果源文件数量多,则将源文件名列在一个文件中,名称间用空格或回车行来进行分隔。然后在 javac 命令行中使用该列表文件名,文件名前冠以 @ 字符。

    源代码文件名称必须含有 .java 后缀,类文件名称必须含有 .class 后缀,源文件和类文件都必须有识别该类的根名。例如,名为 MyClass 的类将写在名为 MyClass.java的源文件中,并被编译为字节码类文件 MyClass.class。

    内部类定义产生附加的类文件。这些类文件的名称将内部类和外部类的名称结合在一起,例如 MyClass$MyInnerClass.class。

    应当将源文件安排在反映其包树结构的目录树中。例如,如果将所有的源文件放在 /workspace 中,那么 com.mysoft.mypack.MyClass 的代码应该在 /workspace/com/mysoft/mypack/MyClass.java 中。

    缺省情况下,编译器将每个类文件与其源文件放在同一目录中。可用 -d 选项(请参阅后面的选项)指定其它目标目录。

    查找类型

    当编译源文件时,编译器常常需要它还没有识别出的类型的有关信息。对于源文件中使用、扩展或实现的每个类或接口,编译器都需要其类型信息。这包括在源文件中没有明确提及、但通过继承提供信息的类和接口。

    例如

    当扩展 java.applet.Applet 时还要用到 Applet 的祖先类:java.awt.Panel 、 java.awt.Container、 java.awt.Component 和 java.awt.Object。

    当编译器需要类型信息时,它将查找定义类型的源文件或类文件。编译器先在自举类及扩展类中查找,然后在用户类路径中查找。用户类路径通过两种途径来定义:通过设置 CLASSPATH 环境变量或使用 -classpath 命令行选项。(有关详细资料,请参阅设置类路径)。如果使用 -sourcepath 选项,则编译器在 sourcepath 指定的路径中查找源文件;否则,编译器将在用户类路径中查找类文件和源文件。可用-bootclasspath 和 -extdirs 选项来指定不同的自举类或扩展类;参阅下面的联编选项。

    成功的类型搜索可能生成类文件、源文件或两者兼有。以下是 javac 对各种情形所进行的处理:

    搜索结果只生成类文件而没有源文件: javac 使用类文件。

    搜索结果只生成源文件而没有类文件: javac 编译源文件并使用由此生成的类文件。

    搜索结果既生成源文件又生成类文件: javac 确定类文件是否过时。若类文件已过时,则 javac 重新编译源文件并使用更新后的类文件。否则, javac 直接使用类文件。

    缺省情况下

    只要类文件比源文件旧, javac 就认为它已过时。( -Xdepend 选项指定相对来说较慢但却比较可靠的过程。)

    注意

    javac 可以隐式编译一些没有在命令行中提及的源文件。用 -verbose 选项可跟踪自动编译。

    文件列表

    为缩短或简化 javac 命令,可以指定一个或多个每行含有一个文件名的文件。在命令行中,采用 '@' 字符加上文件名的方法将它指定为文件列表。当 javac 遇到以 `@' 字符开头的参数时,它对那个文件中所含文件名的操作跟对命令行中文件名的操作是一样的。这使得 Windows 命令行长度不再受限制。

    例如,可以在名为 sourcefiles 的文件中列出所有源文件的名称。该文件可能形如:

    MyClass1.java

    MyClass2.java

    MyClass3.java

    然后可用下列命令运行编译器:

    C:> javac @sourcefiles

    选项

    编译器有一批标准选项,目前的开发环境支持这些标准选项,将来的版本也将支持它。还有一批附加的非标准选项是目前的虚拟机实现所特有的,将来可能要有变化。非标准选项以 -X 打头。

    标准选项

    -classpath 类路径

    设置用户类路径,它将覆盖 CLASSPATH 环境变量中的用户类路径。若既未指定 CLASSPATH 又未指定 -classpath,则用户类路径由当前目录构成。有关详细信息,请参阅设置类路径。

    若未指定 -sourcepath 选项,则将在用户类路径中查找类文件和源文件。

    -d 目录

    设置类文件的目标目录。如果某个类是一个包的组成部分,则 javac 将把该类文件放入反映包名的子目录中,必要时创建目录。例如,如果指定 -d c:/myclasses 并且该类名叫 com.mypackage.MyClass,那么类文件就叫作 c:/myclasses/com/mypackage/MyClass.class。

    若未指定 -d 选项,则 javac 将把类文件放到与源文件相同的目录中。

    注意: -d 选项指定的目录不会被自动添加到用户类路径中。

    -deprecation

    显示每种不鼓励使用的成员或类的使用或覆盖的说明。没有给出 -deprecation 选项的话, javac 将显示这类源文件的名称:这些源文件使用或覆盖不鼓励使用的成员或类。

    -encoding

    设置源文件编码名称,例如 EUCJIS/SJIS。若未指定 -encoding 选项,则使用平台缺省的转换器。

    -g

    生成所有的调试信息,包括局部变量。缺省情况下,只生成行号和源文件信息。

    -g:none

    不生成任何调试信息。

    -g:{关键字列表}

    只生成某些类型的调试信息,这些类型由逗号分隔的关键字列表所指定。有效的关键字有:

    source

    源文件调试信息

    lines

    行号调试信息

    vars

    局部变量调试信息

    -nowarn

    禁用警告信息。

    -O

    优化代码以缩短执行时间。使用 -O 选项可能使编译速度下降、生成更大的类文件并使程序难以调试。

    在 JDK 1.2 以前的版本中,javac 的 -g 选项和 -O 选项不能一起使用。在 JDK 1.2 中,可以将 -g 和 -O 选项结合起来,但可能会得到意想不到的结果,如丢失变量或重新定位代码或丢失代码。-O 选项不再自动打开 -depend 或关闭 -g 选项。同样, -O 选项也不再允许进行跨类内嵌。

    -sourcepath 源路径

    指定用以查找类或接口定义的源代码路径。与用户类路径一样,源路径项用分号 (;) 进行分隔,它们可以是目录、JAR 归档文件或 ZIP 归档文件。如果使用包,那么目录或归档文件中的本地路径名必须反映包名。

    注意

    通过类路径查找的类,如果找到了其源文件,则可能会自动被重新编译。

    -verbose

    冗长输出。它包括了每个所加载的类和每个所编译的源文件的有关信息。

    联编选项

    缺省情况下,类是根据与 javac 一起发行的 JDK 自举类和扩展类来编译。但 javac 也支持联编,在联编中,类是根据其它 Java平台实现的自举类和扩展类来进行编译的。联编时, -bootclasspath 和 -extdirs 的使用很重要;请参阅下面的联编程序示例。

    -target 版本

    生成将在指定版本的虚拟机上运行的类文件。缺省情况下生成与 1.1 和 1.2 版本的虚拟机都兼容的类文件。JDK 1.2 中的 javac 所支持的版本有:

    1.1

    保证所产生的类文件与 1.1 和 1.2 版的虚拟机兼容。这是缺省状态。

    1.2

    生成的类文件可在 1.2 版的虚拟机上运行,但不能在 1.1 版的虚拟机上运行。

    -bootclasspath 自举类路径

    根据指定的自举类集进行联编。和用户类路径一样,自举类路径项用分号 (;) 进行分隔,它们可以是目录、JAR 归档文件或 ZIP 归档文件。

    -extdirs 目录

    根据指定的扩展目录进行联编。目录是以分号分隔的目录列表。在指定目录的每个 JAR 归档文件中查找类文件。

    非标准选项

    -X

    显示非标准选项的有关信息并退出。

    -Xdepend

    递归地搜索所有可获得的类,以寻找要重编译的最新源文件。该选项将更可靠地查找需要编译的类,但会使编译进程的速度大为减慢。

    -Xstdout

    将编译器信息送到System.out 中。缺省情况下,编译器信息送到 System.err 中。

    -Xverbosepath

    说明如何搜索路径和标准扩展以查找源文件和类文件。

    -J选项

    将选项传给 javac 调用的 java 启动器。例如, -J-Xms48m 将启动内存设为 48 兆字节。虽然它不以 -X 开头,但它并不是 javac 的‘标准选项’。用 -J 将选项传给执行用 Java 编写的应用程序的虚拟机是一种公共约定。

    注意

    CLASSPATH 、 -classpath 、 -bootclasspath 和 -extdirs 并 不 指定用于运行 javac 的类。如此滥用编译器的实现通常没有任何意义而且总是很危险的。如果确实需要这样做,可用 -J 选项将选项传给基本的 java 启动器。

    程序示例

    编译简单程序

    一个源文件 Hello.java ,它定义了一个名叫 greetings.Hello 的类。greetings 目录是源文件和类文件两者的包目录,且它不是当前目录。这让我们可以使用缺省的用户类路径。它也使我们没必要用 -d 选项指定单独的目标目录。

    C:> dir

    greetings/

    C:> dir greetings

    Hello.java

    C:> cat greetings/Hello.java

    package greetings;

    public class Hello {

    public static void main(String[] args) {

    for (int i=0; i < args.length; i++) {

    System.out.println("Hello " + args);

    }

    }

    }

    C:> javac greetings/Hello.java

    C:> dir greetings

    Hello.class Hello.java

    C:> java greetings.Hello World Universe Everyone

    Hello World

    Hello Universe

    Hello Everyone

    编译多个源文件

    该示例编译 greetings 包中的所有源文件。

    C:> dir

    greetings/

    C:> dir greetings

    Aloha.java GutenTag.java Hello.java Hi.java

    C:> javac greetings/*.java

    C:> dir greetings

    Aloha.class GutenTag.class Hello.class Hi.class

    Aloha.java GutenTag.java Hello.java Hi.java

    指定用户类路径

    对前面示例中的某个源文件进行更改后,重新编译它:

    C:> cd

    /examples

    C:> javac greetings/Hi.java

    由于 greetings.Hi 引用了 greetings 包中其它的类,编译器需要找到这些其它的类。上面的示例能运行是因为缺省的用户类路径刚好是含有包目录的目录。但是,假设我们想重新编译该文件并且不关心我们在哪个目录中的话, 我们需要将 /examples 添加到用户类路径中。可以通过设置 CLASSPATH 达到此目的,但这里我们将使用 -classpath 选项来完成。

    C:>javac -classpath /examples /examples/greetings/Hi.java

    如果再次将 greetings.Hi 改为使用标题实用程序,该实用程序也需要通过用户类路径来进行访问:

    C:>javac -classpath /examples:/lib/Banners.jar /

    /examples/greetings/Hi.java

    要执行 greetings 中的类,需要访问 greetings 和它所使用的类。

    C:>java -classpath /examples:/lib/Banners.jar greetings.Hi

    将源文件和类文件分开

    将源文件和类文件置于不同的目录下经常是很有意义的,特别是在大型的项目中。我们用 -d 选项来指明单独的类文件目标位置。由于源文件不在用户类路径中,所以用 -sourcepath 选项来协助编译器查找它们。

    C:> dir

    classes/ lib/ src/

    C:> dir src

    farewells/

    C:> dir src/farewells

    Base.java GoodBye.java

    C:> dir lib

    Banners.jar

    C:> dir classes

    C:> javac -sourcepath src -classpath classes:lib/Banners.jar /

    src/farewells/GoodBye.java -d classes

    C:> dir classes

    farewells/

    C:> dir classes/farewells

    Base.class GoodBye.class

    注意:编译器也编译了 src/farewells/Base.java,虽然我们没有在命令行中指定它。要跟踪自动编译,可使用 -verbose 选项。

    联编程序示例

    这里我们用 JDK 1.2 的 javac 来编译将在 1.1 版的虚拟机上运行的代码。

    C:> javac -target 1.1 -bootclasspath jdk1.1.7/lib/classes.zip /

    -extdirs "" OldCode.java

    -target 1.1 选项可确保生成的类文件与 1.1 版的虚拟机兼容。在 JDK1.2 中, 缺省情况下 javac 编译生成的文件是与 1.1 版的虚拟机兼容的,因此并非严格地需要该选项。然而,由于别的编译器可能采用其它的缺省设置,所以提供这一选项将不失为是个好习惯。

    JDK 1.2 javac 在缺省状态下也将根据 1.2 版的自举类来进行编译,因此我们需要告诉 javac 让它根据 JDK 1.1 自举类来进行编译。可用 -bootclasspath 和 -extdirs 选项来达到此目的。不这样做的话,可能会使编译器根据 1.2 版的 API 来进行编译。由于 1.1 版的虚拟机上可能没有该 1.2 版的 API,因此运行时将出错。

    另请参阅

    java

    - Java 应用程序启动器

    jdb

    - Java 应用程序调试程序

    javah

    - C 头文件和 stub 文件生成器

    javap

    - 类文件解析器

    javadoc

    - API 文档生成器

    jar

    - JAR 归档工具 Java 扩展框架

    java: 如果当前在c:/下,要执行的类在D:/java下,则,这个时候,java的命令为

    java -classpath d:/java HelloWorld

    更多相关内容
  • javac

    2021-02-12 11:12:21
    javac
  • 关于nb-javac! “ nb-javac”是OpenJDK“ javac”的补丁版本,即Java编译器。 长期以来,这一直是NetBeans的一部分,它提供了专门针对Java编辑器的经过高度调整的Java编译器,即针对语法着色,代码完成等功能进行...
  • 功能-javac 一个Javac插件,用于提取要插入机器学习模型的特征图 先决条件 JDK 1.10以上 下载 从HEAD构建的最新Extrator版本: ://storage.googleapis.com/features-javac/features-javac-extractor-latest.jar ...
  • 主要演示Java中使用命令打jar包的实例过程,很实用,希望能给大家做一个参考。
  • 刚开始编写java代码时,肯定会遇到各种各样的bug,当然对于初学者这也是能理解的,下面这篇文章主要给大家介绍了关于Java常见问题之javac Hello.java找不到文件解决的相关资料,文中通过图文介绍的非常详细,需要的...
  • 记录搭建java环境终端输入 javac显示不是内部命令错误-附件资源
  • javac-ast-experiments 本项目用于开发示例和实验,以说明和理解如何通过各种javac编译器插件访问和操作javac AST。 该项目目前是以下子项目的容器: javac-ast-reader :这个 maven 项目提供了一个注释处理器的...
  • 该项目可从为支持JSR308的javac编译器提供简单的Maven集成。 用法 克隆并构建Maven-checkerframework-javac 配置Maven编译器插件以使用maven-checkerframework-javac提供的“ javac + jsr308”编译器 从检查器框架...
  • javac -encoding 用法详解

    2020-08-31 23:06:18
    当我们编辑了一个Java源文件保存时,是以操作系统默认的字符编码保存的(Windows xp默认字符集是GBK)。这篇文章主要介绍了javac -encoding 用法详解,非常具有实用价值。
  • NULL 博文链接:https://xjg396.iteye.com/blog/1973026
  • 主要介绍了JAVA和JAVAC 命令详细介绍的相关资料,本文对java 和javac 命令进行了详解,并在Windows和Linux 平台分别说明,需要的朋友可以参考下
  • javac-source-code-reading:javac源码调试
  • NULL 博文链接:https://qn-lf.iteye.com/blog/990975
  • 主要介绍了eclipse javac命令与java命令的相关资料,需要的朋友可以参考下
  • JavaC 从 Java 进行 C 调用的测试
  • Eclipse能后运行的javac源码,从openjdk里剥离出来的,用于学习研究!运行不起可以联系我!
  • java 源码分析 Javac-Research Java语言编译器(javac)源代码学习研究(包括代码注释、文档、用于代码分析的测试用例)
  • linux下 Error running javac compiler
  • ( javac命令的配置

    2018-03-06 09:32:38
    ARM.CMSIS.4.5.0ARM.CMSIS.4.5.0ARM.CMSIS.4.5.0ARM.CMSIS.4.5.0
  • 最近重新复习了一下java基础,这里便讲讲对于一个类文件如何编译、运行、反编译的。也让自己加深一下印象
  • java编译的javac.jar

    2018-07-06 23:24:06
    java编译的javac.jar
  • java jar包,亲测试可用 安全,可以对其进行数字签名,只让能够识别数字签名的用户使用里面的东西。 加快下载速度; 压缩,使文件变小,与ZIP压缩机制完全相同。 ...能够让JAR包里面的文件依赖于统一版本的类文件。...
  • NULL 博文链接:https://1342912960.iteye.com/blog/2235268
  • javac编译成功用java运行class文件出现找不到或无法加载主类 的问题解决起来很简单 2012-06-07 09:25 javac编译成功用java运行class文件出现找不到或无法加载主类 的问题所在很简单 ? 学习android,顺便又学习下java....
  • ##轻量级 javac @Warning 注解 常问问题: 问: @Warning 注释是干什么用的? A:用于从 java 编译器 (javac) 抛出警告消息。 问:何时以及为什么可以使用它? A:当你想将某段代码标记为“危险”或“不稳定”等...
  • javac_可以编译目录.rar

    2018-01-20 23:17:14
    jdk9 javac编译器 源码 当前可以根据用目录作为参数进行编译 谢谢
  • Java命令简易入门2-Javac与Java命令(未完待续) 文章目录Java命令简易入门2-Javac与Java命令(未完待续)基本概念实验环境与实验文件1.javac与java基本用法2. javac的其他常用参数3. 一个文件中包含多个类文件进行...

    Java命令简易入门2-Javac与Java命令之一

    基本概念

    javac与java命令是我们最常用的Java命令。
    javac:Java编译器。负责编译,将.java这个文本文件编译成.class字节码文件。
    java:Java程序启动器。负责启动Java虚拟机(JVM)以运行Java程序。其主要用来载入字节码文件中的主类、执行jar文件等。

    我们可以通过javac --helpjava -help来查看其帮助。

    执行javac -help显示:用法: javac
    其中的source files指的是源代码文件。比如javac HelloWorld.java,生成HelloWorld.class。里面的主类是HelloWorld
    其中的options指的是可选的其他参数。

    执行java -help显示:用法:java [options] <主类> [args…]
    可以看出,其必要参数是主类。注意,是主类而不是文件。因此正确执行命令是java HelloWorld而不是java HelloWorld.class。因为HelloWorld才是主类。

    我们会通过几个实验来简单讲解一下javac与java的基本用法。

    实验环境与实验文件

    OS:Windows 10。
    JDK:AdoptOpenJDK的jdk-11.0.8.10-hotspot

    假设有d:\test\目录下有HelloWorld.java,源代码如下:

    public class HelloWorld{
        public static void main(String[] args) {
            System.out.println("HelloWorld!");
        }
    }
    

    这是一个很单纯的.java文件,里面包含一个主类HelloWorld。我们将在这个代码的基础上逐步扩展,一步步讲解javac与java命令。

    1.javac与java基本用法

    执行如下命令:

    javac -version
    java -version
    javac HelloWorld.java
    java HelloWorld
    

    说明:

    1. 前两个命令用来查看当前命令行下执行的javac与java是什么版本的。
    2. 编译当前目录下的HelloWorld.java文件并在当前路径下生成HelloWorld.class
    3. 启动JVM载入HelloWorld这个主类,从而运行该Java程序。再次强调一下java HelloWorld中的HelloWorld是类名而不是文件名。

    注意:一个系统上可能有多个javac与java命令文件。可以使用where javacwhere java查看系统中的相应的文件。

    命令输出截图如下:
    在这里插入图片描述

    2. javac的其他常用参数

    这里只介绍几个常用的参数。
    -d <directory>:在指定目录(directory)下生成相应的.class文件
    -verbose:输出有关编译器正在执行的操作的消息。

    现在想将编译生成的.class文件自动放在d:\testjava下,如何实现呢?

    del *.class
    del d:\testjava\*.class
    javac -d d:\testjava HelloWorld.java
    dir *.class
    dir d:\testjava\*.class
    

    说明:

    1. del *.class将当前目录下所有.class文件删除,del d:\testjava\*.classd:\testjava\目录下所有.class文件删除。
    2. 编译当前目录下的HelloWorld.java并将生成的.class文件放到d:\testjava目录。注意:d:\testjava可以不用事先建立,该条命令会自动建立。
    3. dir *.class查看当前目录下的.class文件,发现什么都没有
    4. dir d:\testjava\*.class,查看d:\testjava\目录下的所有.class文件。

    命令输出截图如下:
    在这里插入图片描述

    再来看看-verbose参数

    javac -verbose HelloWorld.java

    输出信息如下:

    D:\test>javac -verbose HelloWorld.java
    [语法分析开始时间 SimpleFileObject[D:\test\HelloWorld.java]]
    [语法分析已完成, 用时 12 毫秒]
    [正在加载/modules/jdk.internal.jvmstat/module-info.class]
    [正在加载/modules/java.security.jgss/module-info.class]
    [正在加载/modules/jdk.internal.ed/module-info.class]
    [正在加载/modules/java.xml.crypto/module-info.class]
    [正在加载/modules/java.base/module-info.class]
    [正在加载/modules/java.scripting/module-info.class]
    [正在加载/modules/jdk.security.jgss/module-info.class]
    [正在加载/modules/java.rmi/module-info.class]
    [正在加载/modules/jdk.jfr/module-info.class]
    [正在加载/modules/jdk.dynalink/module-info.class]
    [正在加载/modules/jdk.security.auth/module-info.class]
    [正在加载/modules/java.desktop/module-info.class]
    [正在加载/modules/jdk.unsupported/module-info.class]
    [正在加载/modules/jdk.internal.opt/module-info.class]
    [正在加载/modules/jdk.unsupported.desktop/module-info.class]
    [正在加载/modules/java.instrument/module-info.class]
    [正在加载/modules/jdk.jcmd/module-info.class]
    [正在加载/modules/jdk.jlink/module-info.class]
    [正在加载/modules/jdk.xml.dom/module-info.class]
    [正在加载/modules/jdk.jconsole/module-info.class]
    [正在加载/modules/jdk.jstatd/module-info.class]
    [正在加载/modules/jdk.compiler/module-info.class]
    [正在加载/modules/jdk.internal.vm.ci/module-info.class]
    [正在加载/modules/jdk.jartool/module-info.class]
    [正在加载/modules/java.se/module-info.class]
    [正在加载/modules/jdk.internal.vm.compiler/module-info.class]
    [正在加载/modules/jdk.internal.le/module-info.class]
    [正在加载/modules/jdk.charsets/module-info.class]
    [正在加载/modules/java.net.http/module-info.class]
    [正在加载/modules/java.xml/module-info.class]
    [正在加载/modules/jdk.pack/module-info.class]
    [正在加载/modules/jdk.jsobject/module-info.class]
    [正在加载/modules/jdk.naming.rmi/module-info.class]
    [正在加载/modules/jdk.sctp/module-info.class]
    [正在加载/modules/jdk.jshell/module-info.class]
    [正在加载/modules/jdk.naming.dns/module-info.class]
    [正在加载/modules/jdk.net/module-info.class]
    [正在加载/modules/jdk.scripting.nashorn.shell/module-info.class]
    [正在加载/modules/java.datatransfer/module-info.class]
    [正在加载/modules/jdk.management/module-info.class]
    [正在加载/modules/jdk.httpserver/module-info.class]
    [正在加载/modules/java.sql.rowset/module-info.class]
    [正在加载/modules/java.management/module-info.class]
    [正在加载/modules/jdk.crypto.cryptoki/module-info.class]
    [正在加载/modules/java.management.rmi/module-info.class]
    [正在加载/modules/java.transaction.xa/module-info.class]
    [正在加载/modules/jdk.jdi/module-info.class]
    [正在加载/modules/jdk.management.agent/module-info.class]
    [正在加载/modules/java.security.sasl/module-info.class]
    [正在加载/modules/java.naming/module-info.class]
    [正在加载/modules/jdk.javadoc/module-info.class]
    [正在加载/modules/jdk.accessibility/module-info.class]
    [正在加载/modules/jdk.scripting.nashorn/module-info.class]
    [正在加载/modules/jdk.internal.vm.compiler.management/module-info.class]
    [正在加载/modules/java.prefs/module-info.class]
    [正在加载/modules/java.sql/module-info.class]
    [正在加载/modules/jdk.editpad/module-info.class]
    [正在加载/modules/jdk.jdwp.agent/module-info.class]
    [正在加载/modules/java.smartcardio/module-info.class]
    [正在加载/modules/jdk.attach/module-info.class]
    [正在加载/modules/jdk.zipfs/module-info.class]
    [正在加载/modules/jdk.jdeps/module-info.class]
    [正在加载/modules/jdk.rmic/module-info.class]
    [正在加载/modules/jdk.aot/module-info.class]
    [正在加载/modules/jdk.localedata/module-info.class]
    [正在加载/modules/jdk.crypto.ec/module-info.class]
    [正在加载/modules/jdk.crypto.mscapi/module-info.class]
    [正在加载/modules/java.logging/module-info.class]
    [正在加载/modules/java.compiler/module-info.class]
    [正在加载/modules/jdk.management.jfr/module-info.class]
    [正在加载/modules/jdk.hotspot.agent/module-info.class]
    [源文件的搜索路径: .]
    [类文件的搜索路径: C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\lib\modules,.]
    [正在加载/modules/java.base/java/lang/Object.class]
    [正在加载/modules/java.base/java/lang/String.class]
    [正在加载/modules/java.base/java/lang/Deprecated.class]
    [正在加载/modules/java.base/java/lang/annotation/Retention.class]
    [正在加载/modules/java.base/java/lang/annotation/RetentionPolicy.class]
    [正在加载/modules/java.base/java/lang/annotation/Target.class]
    [正在加载/modules/java.base/java/lang/annotation/ElementType.class]
    [正在检查HelloWorld]
    [正在加载/modules/java.base/java/io/Serializable.class]
    [正在加载/modules/java.base/java/lang/AutoCloseable.class]
    [正在加载/modules/java.base/java/lang/System.class]
    [正在加载/modules/java.base/java/io/PrintStream.class]
    [正在加载/modules/java.base/java/lang/Appendable.class]
    [正在加载/modules/java.base/java/io/Closeable.class]
    [正在加载/modules/java.base/java/io/FilterOutputStream.class]
    [正在加载/modules/java.base/java/io/OutputStream.class]
    [正在加载/modules/java.base/java/io/Flushable.class]
    [正在加载/modules/java.base/java/lang/Comparable.class]
    [正在加载/modules/java.base/java/lang/CharSequence.class]
    [已写入HelloWorld.class]
    [共 181 毫秒]
    

    主要分为几个部分:

    1. 语法分析部分:[语法分析...]
    2. 模块相关部分:[正在加载/modules...]
    3. 源文件搜索部分:[源文件的搜索路径: .]。这里的.指的是当前目录。
    4. 类文件搜索部分1:[类文件的搜索路径: C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\lib\modules,.]
      • 指的是为了编译这个HelloWorld需要在这些路径下搜索相应的类。搜索到后就加载。
      • 这里面的搜索路径有两个,一个是C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\lib\modules还有一个是当前目录。
      • 加载所需使用的Java类库中的最基础的类,比如Object.class、注解相关字节码文件。代码中因为使用了还加载了String.class。
      • 这些类都是在java.base模块。该模块定义Java SE平台的基础API,是基础模块,不依赖于其他模块。
    5. 类文件搜索部分2:[正在检查HelloWorld].
      • 加载HelloWorld这个程序中要用到的其他类。比如System.class,PrintStream.classSystem.out中的out是一个PrintStream类型的对象。
      • 还加载了一些代码中似乎没用到的类和接口。比如,Comparable.class。实际上这个就是Comparable接口。我们的代码中的"HelloWorld!"就是个String对象,其实现了Comparable接口。

    可以看到java不愧是一个面向对象语言,执行一个简单的HelloWrold都要载入这么多类。

    3. 一个文件中包含多个类文件进行编译

    如果一个.java文件中包含多个类的定义,使用javac编译该文件会产生多个.class文件。一个类生成一个.class文件。
    注意:只能有一个public的class。

    public class HelloWorld{
        public static void main(String[] args) {
            System.out.println("HelloWorld");
        }
    }
    class Test{
    
    }
    

    对上述代码使用

    del *.class
    javac -verbose HelloWorld.java
    dir *.class
    

    可以看到如下信息,代表生成了两个.class文件。

    ....
    [已写入HelloWorld.class]
    ...
    [已写入Test.class]
    

    之后使用dir *.class也可进行验证。

    4. 类路径参数:-cp或-classpath

    类路径参数也是一个重要参数,格式为: -classpath <path>-cp <path>
    -cp-classpath的缩写。
    该参数告诉java编译器,在编译某个文件时,去哪个路径去寻找该java代码文件所需要用到的类。因此称之为类路径。

    比如d:\test有如下代码:

    public class HelloWorld{
        public static void main(String[] args) {
            Test test = new Test();
            System.out.println("HelloWorld");
        }
    }
    

    很明显,编译该文件需要一个Test类,然而Test类并未在该文件中有定义。
    如果直接执行javac HelloWorld.java,那么其会在当前目录下寻找Test.class。如果没找到,会报错。

    有了-cp参数,我们就可以将类所需的其他.class放置到另外一个目录,编译的时候可以指定编译器的查找该路径。

    了解了这个原理,我们可以自己做一个实验:

    1. d:\testjava\目录下新建一个Test.java,代码很简单public class Test{}
    2. 进行编译。生成的Test.class在d:\testjava\目录下。
    3. 再执行javac -cp d:\testjava\ HelloWorld.java,就可以顺利完成编译。

    事实上,即使你不手动编译Test.java,上面那条javac命令也会在d:\testjava\下寻找Test.java文件。如果有,就自动编译。

    总结

    1. javac可以将.java文件编译成字节码文件。
    2. Java 11中的javac编译时,使用到了模块系统。所有java程序都需要java.base模块。
    3. 编译时会将程序所需类与接口全部导入。
    4. Java将类的信息都存储在.class文件中。启动Java程序时,会从.class文件中载入相关类。
    5. -d参数可以在指定目录(directory)下生成相应的.class文件。
    6. -cp参数可以帮java编译器寻找相应的类。这个参数很重要,应当理解。IDE中虽然不需要使用命令行,但如果用到第三方库,可能就需要对Build Path进行设置。这种设置实际上就是修改了相应的类路径。

    动动手

    在HelloWorld.java代码的基础上,分别对如下几种情况,使用javac -verbose HelloWorld.java来观察输出信息。并分析,这些错误都发生在哪几个阶段?

    1. 在HelloWorld.java的代码中添加错误。比如,将冒号 ; 去掉。
    2. String[] args改成string[] args
    3. 在main方法中添加Person p = new Person();

    参考资料

    1. “Hello World!” for Microsoft Windows
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 238,424
精华内容 95,369
关键字:

javac

友情链接: JGB28181-master.zip