【问题标题】:Java Circular Reference - Can’t CompileJava 循环参考 - 无法编译
【发布时间】:2013-08-13 20:31:28
【问题描述】:

文件: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,它的依赖项是一个曲折的小短语迷宫。

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

有灵丹妙药吗?

【问题讨论】:

  • 这应该在 Java 中编译得很好。
  • 确实在Java中编译得很好,除了public foo(A a) {...}的编译错误(缺少返回类型)。
  • 循环部。不好,但它们可以编译。
  • 你的 foo 应该是 void foo(...) ,但我猜你已经知道了。
  • 魔法子弹的拼写是 c l a s s p a t h :)

标签: java circular-dependency


【解决方案1】:

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

javac A.java B.java

【讨论】:

  • javac -classpath 。只要 B.java 在同一个包中,A.java 也应该可以正常编译。或者只要它可以在类路径中找到。
  • 它编译得很好,但是 not 因为 -classpath 指令:首先,它没有它也可以工作(因为当前目录默认包含在两个自 Java 5 以来的 classpath 和 sourcepath),其次,此处使用的选项是 -sourcepath,而不是 -classpath(因为 javac 将在此处查找 source 文件) -- 参见手册。
【解决方案2】:

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

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

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 尚未编译,它甚至会编译!)

【讨论】:

  • -classpath 与 *.java 文件无关(顾名思义)。您正在寻找的选项是 -sourcepath (如果没有明确设置,它会回退到 classpath)。
【解决方案3】:

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

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 -- 但不相互依赖

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-01
    • 2013-06-27
    • 1970-01-01
    • 2015-09-28
    • 2013-04-03
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多