3

文件:A.java

class A
{
    B b;
    public A() {
        b = new B();
    }
}

文件:B.java

class B
{
    public B() {}
    public foo(A a) {...}
}

上面的代码无法编译,因为 A 需要 B 才能编译,B 需要 A 才能编译。两者都不应在另一个之前编译。怎么办?

这个例子很简单。我可以删除 foo(A a) {...} 这样的 B.java 会编译。然后编译A.java。恢复 B.java 然后编译它。但我正在尝试从源代码构建 RXTX,它的依赖项是一个曲折的小短语迷宫。

我曾希望我可以编译为非工作类代码。然后将所有定义的类和方法再次编译成工作代码。

有灵丹妙药吗?

4

3 回答 3

7

如果您同时编译它们,它们应该可以正常编译:

javac A.java B.java
于 2013-08-13T20:34:44.720 回答
3

如果您使用 Java IDE(Eclipse 或 Netbeans 等)或 ant 构建脚本等(主要是使用javac命令时它应该是正确的类路径),则没有编译问题。

或者如果你从命令行编译 ,*.javajavac这更聪明;)

javac -classpath ... *.java

Java 编译器在您的类路径中工作,这是 Java 中的第一条规则!

如果您拥有 A 和 B 源代码,并且使用正确的类路径进行编译,那么 javac 任务就没有问题。

如果您只是编译您的第一个类(A 或 B),Java 编译器将在类路径中搜索请求的类(如导入中指定的那样,如果没有给出导入包,则类路径应为选定的类)。

如果 A.java 和 B.java 在同一个包中,并且您确实运行javac -classpath 。A.java这应该会导致 A.class 和 B.class 在运行中。

如果 A.java 在包 x 中,B 在包 y 中,那么您当然应该在编译期间同时使用这两个类路径。javac -classpath x;y;.; A.java(如果还没有编译,这甚至会编译 B.java!)

于 2013-08-13T20:35:51.813 回答
0

或者,通过使用接口来打破循环依赖——当然,如果这适用于您的情况。

c.java:

public interface C {...};

B.java:

public class B implements C {...};

A.java:

class A
{
    C b;
    public A() {
        b = // use a factory here, returning a C reference
    }
}

因此,在编译时,A 和 B 都依赖于 C——但不相互依赖

于 2016-07-01T21:58:17.957 回答