我是一名经验丰富的程序员,但多年来一直没有使用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());
}
}
sourceClass编译时没有“javac src / * .java”的问题,从“ProjectName”目录运行。我希望看到这个失败,并出现“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
我尝试过很多东西 - 添加一个import语句,在javac命令中添加一个源路径,将sourceClass编译为jar并将其放入bin目录然后将其添加到类路径中,但我不能得到测试以找到SourceClass符号。
知道我在这里缺少什么吗?
答案 0 :(得分:2)
如果您编译到单独的目标目录中,它将起作用。 E.g,
mkdir target
javac -d target/ src/*.java
javac -classpath target/ test/*.java
执行javac src/*.java
时,它会在.class
目录中创建src
文件。默认情况下,您引用的任何类都假定在同一个包中。因此,即使您将src/
添加到类路径,它也会查找它找不到的src/ProjectName/SourceClass.class
。当您传递-d target/
选项时,它会创建正确的包层次结构,因此会找到该类。
javac official doc的相关文档:
您应该将源文件排列在反映的目录树中 他们的包树。例如,如果您保留所有源文件 C:\ workspace,com.mysoft.mypack.MyClass的源代码应该是 在C:\ workspace \ com \ mysoft \ mypack \ MyClass.java。
默认情况下,编译器将每个类文件放在同一目录中 它的源文件。您可以使用指定单独的目标目录 -d(参见下面的选项)。
...
...
-d 目录设置类文件的目标目录。该目录必须已存在; javac不会创建它。如果是一个班级 作为包的一部分,javac将类文件放在子目录中 反映包名称,根据需要创建目录。对于 例如,如果指定-d C:\ myclasses并调用该类 com.mypackage.MyClass,然后调用类文件 C:\ myclasses \ COM \ mypackage中\ MyClass.class。如果未指定-d, javac将每个类文件放在与源文件相同的目录中 从中生成。
注意:-d指定的目录不会自动添加到您的 用户类路径。
答案 1 :(得分:1)
我的猜测是它无法找到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
答案 2 :(得分:0)
可接受的答案是正确的,但是它遗漏了一个关键点:当要求javac编译*.java
(而不是foo.java
然后是foo2.java
...)时,它会处理它们作为一个单独的包,并接受它们之间的引用。
那是魔术。其他语言对头文件的隐式处理较少。
即使在阅读了这篇文章之后,我还是花了一些时间才弄清楚,与我固有的假设相反,一个程序在文件上一个接一个地运行将产生(应该)产生与在一组磁盘上运行该程序相同的结果。文件。我的错; *
不仅是方便,而且很重要。