我是一位经验丰富的程序员,但多年来没有使用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符号。
知道我在这里缺少什么吗?
如果编译到一个单独的目标目录中,它将起作用。例如,
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指定的目录不会自动添加到您的用户类路径。
我猜是找不到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
...)时,它将它们视为单个包并接受它们之间的引用。
这就是魔术。其他语言对头文件的隐式处理较少。
即使在阅读了这篇文章之后,我花了一些时间才弄清楚,与我固有的假设相反,一个程序在文件上一个接一个地运行将产生(应该)产生与在一组文件上运行该程序相同的结果。 。我的错; *
不仅是方便,而且很重要。