当类存在于类路径中时,我该如何防止Java隐式编译?

6
假设我有两个类(Bob和Tom),其中Bob使用Tom,但Tom不需要Bob。这两个文件都位于同一目录结构中。
public class Bob {
  public static void main(String[] args) {
    System.out.println(Tom.MESSAGE);
  }
}

public class Tom {
  public static String MESSAGE = "Hello World";
}

如果我尝试以典型方式编译Bob,我可以使它隐式地编译Tom.java,因为它被认为是Bob.java的依赖项。这很好。但是现在假设我想把Tom放在一个JAR文件中。所以我构建了Tom.java并将结果放入一个JAR文件:libTom.jar。现在我使用类路径指向libTom.jar进行编译。不幸的是,编译器看到Tom.java文件并导致它被编译,而不是使用libTom.jar中的类。如果在类路径中找到类,有没有办法让编译器跳过对Tom.java的隐式构建?我意识到这个例子相当牵强,但请放心,周围有一个更复杂、更不牵强的用例涉及到这个问题。谢谢。

3
虽然我没有使用过它,但你是否尝试过javac的“-implicit”标志?根据帮助输出:“-implicit:{none,class} 指定是否为隐式引用的文件生成类文件”,这听起来像是你想要的。 - Steve B.
为什么那不是一个答案?@SteveB. - 11684
4个回答

1

如果在类路径中有两个同名且在同一包中的类,那么当Java编译代码时很难预测哪一个会被选中。如果源代码中存在Tom类,则它肯定会被选中。

你可以通过将其中一个Tom放入不同的包中来避免这种情况。另一种方法是将当前的Tom移动到一个单独的项目中。我知道这些方法可能对你来说都不实际。如果真的有必要,你可以尝试编写自己的ClassLoader。参考此问题:Jar hell: how to use a classloader to replace one jar library version with another at runtime


1

看起来这是不可能的,这正是我一开始担心的。


0

是的,您可以通过输入类的完整名称来实现,即键入

System.out.println(the.package.of.external.Tom.MESSAGE);
System.out.println(the.current.package.Tom.MESSAGE);


抱歉,我可能在这个元素上表达得不够清楚。所提到的“Tom”类是完全相同的类。因此,包将是相同的包。我只是想避免在类已经被编译的情况下进行隐式编译,以免浪费时间。 - Viper Bailey
啊哈...你可以把源代码放在另一个目录中,并且使用“import”命令导入该类。 - 11684
你可以尝试使用JRebel,它可能会对你有所帮助。@ViperBailey - 11684

0
你能把Java文件分成不同的源代码目录吗? 这样做是有意义的,因为你可以从一个源代码目录中构建jar包,然后在编译其他一组文件时只需包含另一个源代码目录。 在Eclipse中,这种方法非常有效。 更好的方法是在Eclipse中使用两个项目。

由于我正在尝试解决的特定问题的性质,那样做行不通。 - Viper Bailey
你可能需要更详细地解释具体的问题,然后再进行处理。 - davidfrancis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接