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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:16:55  来源:igfitidea点击:

How does javac automatically compile dependencies of a class

javaimportpackagejavac

提问by paidedly

Given the following directory structure:

给定以下目录结构:

/top
   |--- wrk
          |--- pkg
                  |--- A.java
                  |--- B.java

Assume that the two files A.javaand B.javacontain 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.javawork 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/pkgthen the command javac A.javaworks. 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.javaas well since both A.javaand B.javaare in the same package. This will work even If B.javawas in a different package from A.java(provided Bis public) as long as both the packages are present in the wrkdirectory and you compile A.javafrom wrkdirectory.

当你编译A.java,编译;B.java以及因为两者A.javaB.java都在同一个包。只要这两个包都存在于目录中并且您从目录中编译,即使B.java它与A.java(提供的B是公共的)位于不同的包中,这也将起作用。wrkA.javawrk

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 sourcepathwill also be .since the default sourcepathis the same as the CLASSPATH. You can confirm that the default sourcepath is set to .by compiling A.javausing javac -verbose -g pkg\A.java. Notice that the compiler is looking in the current directory for .javafiles :

如果您尚未设置CLASSPATH,则默认为.。随后,sourcepath也将是,.因为默认值sourcepathCLASSPATH. 您可以.通过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 sourcepathis set to CLASSPATH, you can try changing the CLASSPATHusing the -cpoption by compiling A.javausing javac -cp C:\ -verbose -g pkg\A.java. A.javawill not compile this time since you have overwritten the CLASSPATHto C:\and that's what sourcepathwill default to as well. This is the output :

要确认sourcepath设置为CLASSPATH,您可以尝试通过编译using 来更改CLASSPATHusing-cp选项。这次不会编译,因为您已经覆盖了to并且这也是默认值。这是输出:A.javajavac -cp C:\ -verbose -g pkg\A.javaA.javaCLASSPATHC:\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.classis 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 引用它。