java javac如何自动编译类的依赖
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30527632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does javac automatically compile dependencies of a class
提问by paidedly
Given the following directory structure:
给定以下目录结构:
/top
|--- wrk
|--- pkg
|--- A.java
|--- B.java
Assume that the two files A.java
and B.java
contain the following code, respectively:
假设两个文件A.java
,并B.java
包含下面的代码,分别为:
// Filename: A.java
package pkg;
class A { B b; }
// Filename: B.java
package pkg;
class B {...}
Assuming that the current directory is /top/wrk
假设当前目录是 /top/wrk
Why does the command javac -cp . pkg/A.java
work successfully even though we have not yet compiled B.java
?
为什么javac -cp . pkg/A.java
即使我们还没有编译命令也能成功运行B.java
?
Also if the current directory is /top/wrk/pkg
then the command javac A.java
works. How so?
此外,如果当前目录是,/top/wrk/pkg
则该命令javac A.java
有效。怎么会这样?
采纳答案by CKing
Why does the command javac -cp . pkg/A.java work successfully even though we have not yet compiled B.java
为什么命令 javac -cp 。即使我们还没有编译 B.java,pkg/A.java 也能成功运行
When you compile A.java
, the compiler will compile B.java
as well since both A.java
and B.java
are in the same package. This will work even If B.java
was in a different package from A.java
(provided B
is public) as long as both the packages are present in the wrk
directory and you compile A.java
from wrk
directory.
当你编译A.java
,编译;B.java
以及因为两者A.java
并B.java
都在同一个包。只要这两个包都存在于目录中并且您从目录中编译,即使B.java
它与A.java
(提供的B
是公共的)位于不同的包中,这也将起作用。wrk
A.java
wrk
From the Oracle documentationfor javac
:
从Oracle文档为javac
:
If the -sourcepath option is not specified, the user class path is also searched for source files.
如果未指定 -sourcepath 选项,还会在用户类路径中搜索源文件。
From the Oracle documentfor CLASSPATH
从Oracle 文档中获取CLASSPATH
The default value of the class path is "."
类路径的默认值为“.”。
If you haven't set a CLASSPATH
, it will be defaulted to .
. Subsequently, the sourcepath
will also be .
since the default sourcepath
is the same as the CLASSPATH
. You can confirm that the default sourcepath is set to .
by compiling A.java
using javac -verbose -g pkg\A.java
. Notice that the compiler is looking in the current directory for .java
files :
如果您尚未设置CLASSPATH
,则默认为.
。随后,sourcepath
也将是,.
因为默认值sourcepath
与CLASSPATH
. 您可以.
通过A.java
使用javac -verbose -g pkg\A.java
. 请注意,编译器正在当前目录中查找.java
文件:
[parsing started pkg\A.java]
[parsing completed 29ms]
[search path for source files: [.]]
[parsing started pkg\A.java]
[parsing completed 29ms]
[search path for source files: [.]]
To confirm that the sourcepath
is set to CLASSPATH
, you can try changing the CLASSPATH
using the -cp
option by compiling A.java
using javac -cp C:\ -verbose -g pkg\A.java
. A.java
will not compile this time since you have overwritten the CLASSPATH
to C:\
and that's what sourcepath
will default to as well. This is the output :
要确认sourcepath
设置为CLASSPATH
,您可以尝试通过编译using 来更改CLASSPATH
using-cp
选项。这次不会编译,因为您已经覆盖了to并且这也是默认值。这是输出:A.java
javac -cp C:\ -verbose -g pkg\A.java
A.java
CLASSPATH
C:\
sourcepath
[parsing started pkg\A.java]
[parsing completed 26ms]
[search path for source files: [C:\]]
pkg\A.java:3: cannot find symbol
symbol : class B
[parsing started pkg\A.java]
[parsing completed 26ms]
[search path for source files: [C:\]]
pkg\A.java:3: cannot find symbol
symbol : class B
Also if the current directory is /top/wrk/pkg then the command javac A.java works. How so?
此外,如果当前目录是 /top/wrk/pkg 则命令 javac A.java 有效。怎么会这样?
This will not work regardless of whether B.class
is present in pkg
无论是否B.class
存在,这都不起作用pkg
Disclaimer :I can only confirm this behavior on Windows but I highly doubt that it should be any different on other operating systems.
免责声明:我只能在 Windows 上确认这种行为,但我非常怀疑它在其他操作系统上是否应该有所不同。
回答by Phil Anderson
From the Oracle javac docs...
从Oracle javac 文档...
If you set the -sourcepath option, then the compiler searches the indicated path for source files. Otherwise, the compiler searches the user class path for both class files and source files. On Windows, the -sourcepath option seems to be set by default and your command works.
如果您设置了 -sourcepath 选项,那么编译器会在指定的路径中搜索源文件。否则,编译器会在用户类路径中搜索类文件和源文件。在 Windows 上,-sourcepath 选项似乎是默认设置的,并且您的命令有效。
On my Mac though, it fails and gives following message...
但在我的 Mac 上,它失败并给出以下消息...
A.java:5: error: cannot find symbol
B b;
^
symbol: class B
location: class A
1 error
To get it to automatically look and compile source files of dependencies, you would need to use the -sourcepath option. e.g...
要让它自动查找和编译依赖项的源文件,您需要使用 -sourcepath 选项。例如..
javac -sourcepath ./* A.java
回答by vempo
The compiler has to either find and successfully compile a source for B, or find a .class for B even if it's just an import. As opposed to loading, which is done dynamically.
编译器要么找到并成功编译 B 的源代码,要么为 B 找到一个 .class,即使它只是一个导入。与加载相反,加载是动态完成的。
Look in your output directory and you'll see that B has been compiled as well. It will be compiled even if in a different package, but you'll have to make it public to reference it from A.
查看您的输出目录,您会看到 B 也已编译。即使在不同的包中,它也会被编译,但您必须将其公开以从 A 引用它。