您的位置 首页 java

jvm – javac工具

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

语法结构

javac [ options ] [ sourcefiles ] [ @files ]

options

命令行选项。参数可按随意次序排列。

sourcefiles

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

@files

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

命令说明

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

  • 假设源文件数量少,在命令行上列出文件名称就可以。
  • 假设源文件数量多,则将源文件名称列在一个文件里,名称间用空格或回车行来进行分隔。然后在 javac 命令行中使用该列表文件名称,文件名称前冠以 @ 字符。

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

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

应当将源文件安排在反映其包树结构的文件夹树中。比如,假设将全部的源文件放在 /workspace 中,那么 com.mysoft.mypack.MyClass 的代码应该在 \workspace\com\mysoft\mypack\MyClass.java 中。

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

查找类型(sourcefiles)

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

比如,当扩展 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 就觉得它已过时。( -Xdepend 选项指定相对来说较慢但却比较可靠的过程。)

注意: javac 能够隐式编译一些沒有在命令行中提及的源文件。用 -verbose 选项可跟踪主动编译的过程。

文件列表(@files)

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

比如,能够在名为 sourcefiles 的文件里列出全部源文件的名称。该文件可能形如:

MyClass1.java

MyClass2.java

MyClass3.java

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

C:> javac @sourcefiles

选项(options)

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

1)标准选项

-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

设置源文件编码名称,比如 UTF-8。若未指定 -encoding 选项,则使用平台缺省的编码器。

-g

生成全部的调试信息,包含局部变量。缺省情况下,仅仅生成行号和源文件信息。

-g:none

不生成不论什么调试信息。

-g :{keyword列表}

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

source

源文件调试信息

lines

行号调试信息

vars

局部变量调试信息

-nowarn

禁用警告信息。

-O

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

-sourcepath 源路径

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

注意:通过类路径查找的类,假设找到了其源文件,则可能会自己主动被又一次编译。

-verbose

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

-source 版本号

规定接受的源代码版本,可以是下面的版本:

1.3

The compiler does not support assertions, generics, or other language features introduced after Java SE 1.3.

1.4

The compiler accepts code containing assertions, which were introduced in Java SE 1.4.

1.5

The compiler accepts code containing generics and other language features introduced in Java SE 5.

5

Synonym for 1.5.

1.6

No language changes were introduced in Java SE 6. However, encoding errors in source files are now reported as errors instead of warnings as in previous releases of Java SE.

6

Synonym for 1.6.

1.7

This is the default value. The compiler accepts code with features introduced in Java SE 7.

7

Synonym for 1.7.

2)联编选项

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

-target 版本号

生成将在指定版本号的虚拟机上执行的类文件。可以是下面的版本号:

1.3

The compiler does not support assertions, generics, or other language features introduced after Java SE 1.3.

1.4

The compiler accepts code containing assertions, which were introduced in Java SE 1.4.

1.5

The compiler accepts code containing generics and other language features introduced in Java SE 5.

5

Synonym for 1.5.

1.6

No language changes were introduced in Java SE 6. However, encoding errors in source files are now reported as errors instead of warnings as in previous releases of Java SE.

6

Synonym for 1.6.

1.7

This is the default value. The compiler accepts code with features introduced in Java SE 7.

7

Synonym for 1.7.

-bootclasspath 自举类路径

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

-extdirs 文件夹

依据指定的扩展文件夹进行联编。文件夹是以分号分隔的文件夹列表。在指定文件夹的每一个 JAR 归档文件里查找类文件。

3)非标准选项

-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 启动器。

例子

1) 编译简单程序

一个源文件 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[i]);

}

}

}

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

2) 编译多个源文件

该演示例子编译 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

3) 指定用户类路径

对前面演示例子中的某个源文件进行更改后,又一次编译它:

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

4)将源文件和类文件分开

将源文件和类文件置于不同的文件夹下常常是非常有意义的,特别是在大型的项目中。我们用 -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 选项。

5)联编程序

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

C\:>javac -source 1.6 -target 1.6 -bootclasspath C:\jdk1.6.0\lib\rt.jar -extdirs “” OldCode.java

-source 1.6 使用java 1.6 去编译 OldCode.java.

-target 1.6 生成和1.6 Jvm兼容的class文件,大多数情况下,这里的值要保持和 -source 一致。

-bootclasspath : 指定java 1.6对应的启动类的路径,如果不指向正确的1.6的启动类所在的文件路径,将会产生以下告警:

C:\>javac -source 1.6 OldCode.java
warning: [options] bootstrap class path not set in conjunction with -source 1.6

Note: If you do not specify the correct version of bootstrap classes, the compiler will use the old language rules (in this example, it will use version 1.6 of the Java programming language) combined with the new bootstrap classes(in this case, Java SE 7), which can result in class files that do not work on the older platform (in this case, Java SE 6) because reference to non-existent methods can get included.

参考资料

文章来源:智云一二三科技

文章标题:jvm – javac工具

文章地址:https://www.zhihuclub.com/183545.shtml

关于作者: 智云科技

热门文章

网站地图