[英]java compiling from the command line
我是一名经验丰富的程序员,但多年未使用 Java - 主要是 C# - 并且过去使用过 IDE。 我正在尝试从 Mac 上的命令行编译一些代码,但无法让我的测试文件找到我的源代码。 我假设问题出在包、文件结构、类路径和导入语句的空间中 - 但我已经投入了几个小时(包括在 Stack Overflow 上寻找)并且仍然卡住了。
这是我所拥有的:
Directory structure:
ProjectName
|
--src
|
--SourceClass
--test
|
--SourceClassTest
--external
|
--testng-6.8.7.jar
我的 SourceClass 看起来像这样:
package ProjectName;
public class SourceClass<T>{
}
很简单。 显然,还会有更多 - 但我想首先确保在我实际进行编码之前所有这些设置都是正确的。
我的测试类如下所示:
package ProjectName;
import java.util.*;
import org.testng.Assert;
import org.testng.annotations.*;
public class SourceClassTest{
@Test
private void createEmptySourceClass(){
SourceClass<Object> sourceClass = new SourceClass<Object>();
Assert.assertTrue(sourceClass.isEmtpy());
}
}
从“ProjectName”目录运行的“javac src/*.java”编译源类没有问题。 我想看到这个失败并出现“SourceClass 没有 isEmpty() 方法”这样的错误,但是我从“ProjectName”目录中像这样运行 javac:
javac test/*.java -classpath external/testng-6.8.7.jar
并得到这个例外:
test/SourceClassTest.java:12: error: cannot find symbol
SourceClass<Object> tree = new SourceClass<Object>();
^
symbol: class SourceClass
location: class SourceClassTest
test/SourceClassTest.java:12: error: cannot find symbol
SourceClass<Object> sourceClass = new SourceClass<Object>();
^
symbol: class SourceClass
location: class SourceClassTest
2 errors
我尝试了很多事情 - 添加导入语句,向 javac 命令添加源路径,将 sourceClass 编译为 jar 并将其放入 bin 目录中,然后将其添加到类路径中,但我无法进行测试找到 SourceClass 符号。
知道我在这里缺少什么吗?
如果您编译到单独的目标目录中,它会起作用。 例如,
mkdir target
javac -d target/ src/*.java
javac -classpath target/ test/*.java
当您执行javac src/*.java
,它将在src
目录本身中创建.class
文件。 默认情况下,假定您引用的任何类都在同一个包中。 因此,即使您将src/
添加到类路径,它src/ProjectName/SourceClass.class
查找src/ProjectName/SourceClass.class
,但它没有找到。 当您传递-d target/
选项时,它会创建正确的包层次结构,因此并找到该类。
javac 官方文档中的相关文档:
您应该在反映其包树的目录树中排列源文件。 例如,如果您将所有源文件保存在 C:\\workspace 中,则 com.mysoft.mypack.MyClass 的源代码应位于 C:\\workspace\\com\\mysoft\\mypack\\MyClass.java 中。
默认情况下,编译器将每个类文件放在与其源文件相同的目录中。 您可以使用 -d 指定单独的目标目录(请参阅下面的选项)。
...
...
-d directory设置类文件的目标目录。 该目录必须已经存在; javac 不会创建它。 如果类是包的一部分,javac 会将类文件放在反映包名称的子目录中,并根据需要创建目录。 例如,如果指定 -d C:\\myclasses 并且类名为 com.mypackage.MyClass,则类文件名为 C:\\myclasses\\com\\mypackage\\MyClass.class。 如果未指定 -d,则 javac 将每个类文件放在与生成它的源文件相同的目录中。
注意:-d 指定的目录不会自动添加到您的用户类路径中。
我的猜测是它找不到 SourceClass 因为定义该类的文件在src
下,并且您没有在 javac 命令行中提到该目录。
如果我是你,我会将文件层次结构更改为:
ProjectName/src/ProjectName/SourceClass.java
ProjectName/src/ProjectName/SourceClassTest.java
ProjectName/external/testng-6.8.7.jar
然后运行javac src/ProjectName/*.java -classpath external/testng-6.8.7.jar
。
或者保持文件层次结构不变,然后运行javac src/*.java test/*.java -classpath external/testng-6.8.7.jar
接受的答案是正确的,但它错过了一个关键点:当 javac 被要求编译*.java
(而不是foo.java
,然后是foo2.java
...)时,它会将它们视为一个包并接受之间的引用他们。
这就是魔法。 其他语言使用头文件隐式地做到这一点。
即使在阅读了这篇文章之后,我还是花了一些时间来弄清楚这一点,这与我固有的假设相反,即一个程序一个接一个地在文件上运行会(应该)产生与在一组文件上运行该程序相同的结果。 我的坏; *
不仅仅是为了方便,而是至关重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.