繁体   English   中英

java从命令行编译

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM