javac如何自动编译一个class的依赖
How does javac automatically compile dependencies of a class
给定以下目录结构:
/top
|--- wrk
|--- pkg
|--- A.java
|--- B.java
假设A.java
和B.java
两个文件分别包含如下代码:
// Filename: A.java
package pkg;
class A { B b; }
// Filename: B.java
package pkg;
class B {...}
假设当前目录为/top/wrk
为什么我们还没有编译 B.java
命令 javac -cp . pkg/A.java
就可以成功运行?
此外,如果当前目录是 /top/wrk/pkg
,则命令 javac A.java
有效。为何如此?
编译器必须找到并成功编译 B 的源代码,或者找到 B 的 .class,即使它只是一个导入。与动态加载相反。
查看您的输出目录,您会看到 B 也已编译。即使在不同的包中,它也会被编译,但你必须public才能从 A.
中引用它
Why does the command javac -cp . pkg/A.java work successfully even though we have not yet compiled B.java
当您编译 A.java
时,编译器也会编译 B.java
,因为 A.java
和 B.java
都在同一个包中。即使 B.java
与 A.java
在不同的包中(前提是 B
是 public),只要这两个包都存在于 wrk
中,这也将起作用目录,然后从 wrk
目录编译 A.java
。
来自 Oracle documentation for javac
:
If the -sourcepath option is not specified, the user class path is also searched for source files.
来自 Oracle document for CLASSPATH
The default value of the class path is "."
如果您没有设置 CLASSPATH
,它将默认为 .
。随后,sourcepath
也将是 .
,因为默认的 sourcepath
与 CLASSPATH
相同。您可以通过使用 javac -verbose -g pkg\A.java
编译 A.java
来确认默认源路径设置为 .
。请注意,编译器正在当前目录中查找 .java
个文件:
[parsing started pkg\A.java]
[parsing completed 29ms]
[search path for source files: [.]]
要确认 sourcepath
设置为 CLASSPATH
,您可以尝试使用 -cp
选项通过编译 A.java
来更改 CLASSPATH
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
Also if the current directory is /top/wrk/pkg then the command javac
A.java works. How so?
无论 B.class
是否存在于 pkg
中,这都不起作用
免责声明: 我只能在 Windows 上确认此行为,但我非常怀疑它在其他操作系统上应该有什么不同。
来自 Oracle javac docs...
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.
不过在我的 Mac 上,它失败并给出以下消息...
A.java:5: error: cannot find symbol
B b;
^
symbol: class B
location: class A
1 error
要让它自动查找和编译依赖源文件,您需要使用-sourcepath 选项。例如...
javac -sourcepath ./* A.java
给定以下目录结构:
/top
|--- wrk
|--- pkg
|--- A.java
|--- B.java
假设A.java
和B.java
两个文件分别包含如下代码:
// Filename: A.java
package pkg;
class A { B b; }
// Filename: B.java
package pkg;
class B {...}
假设当前目录为/top/wrk
为什么我们还没有编译 B.java
命令 javac -cp . pkg/A.java
就可以成功运行?
此外,如果当前目录是 /top/wrk/pkg
,则命令 javac A.java
有效。为何如此?
编译器必须找到并成功编译 B 的源代码,或者找到 B 的 .class,即使它只是一个导入。与动态加载相反。
查看您的输出目录,您会看到 B 也已编译。即使在不同的包中,它也会被编译,但你必须public才能从 A.
中引用它Why does the command javac -cp . pkg/A.java work successfully even though we have not yet compiled B.java
当您编译 A.java
时,编译器也会编译 B.java
,因为 A.java
和 B.java
都在同一个包中。即使 B.java
与 A.java
在不同的包中(前提是 B
是 public),只要这两个包都存在于 wrk
中,这也将起作用目录,然后从 wrk
目录编译 A.java
。
来自 Oracle documentation for javac
:
If the -sourcepath option is not specified, the user class path is also searched for source files.
来自 Oracle document for CLASSPATH
The default value of the class path is "."
如果您没有设置 CLASSPATH
,它将默认为 .
。随后,sourcepath
也将是 .
,因为默认的 sourcepath
与 CLASSPATH
相同。您可以通过使用 javac -verbose -g pkg\A.java
编译 A.java
来确认默认源路径设置为 .
。请注意,编译器正在当前目录中查找 .java
个文件:
[parsing started pkg\A.java]
[parsing completed 29ms]
[search path for source files: [.]]
要确认 sourcepath
设置为 CLASSPATH
,您可以尝试使用 -cp
选项通过编译 A.java
来更改 CLASSPATH
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
Also if the current directory is /top/wrk/pkg then the command javac A.java works. How so?
无论 B.class
是否存在于 pkg
免责声明: 我只能在 Windows 上确认此行为,但我非常怀疑它在其他操作系统上应该有什么不同。
来自 Oracle javac docs...
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.
不过在我的 Mac 上,它失败并给出以下消息...
A.java:5: error: cannot find symbol
B b;
^
symbol: class B
location: class A
1 error
要让它自动查找和编译依赖源文件,您需要使用-sourcepath 选项。例如...
javac -sourcepath ./* A.java