为什么重新安排Java导入导致代码不再编译?
我认为Java导入的顺序对于代码的语义并不重要,这使得它成为一种安全的操作。编辑器使组织/优化/重新排列Java导入语句变得非常容易,并且一些样式检查/分析工具将强制执行订单。我没有成功找到在线发帖,提到重新安排进口的危险。但是,我现在遇到了重新排列导入导致代码中断的情况。
以下代码无法编译,说它无法找到符号Retention
:
package foo;
import foo.BadImportsTest.TestOptions.Option;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.Assert;
import org.junit.Test;
public final class BadImportsTest {
@Retention(RetentionPolicy.RUNTIME)
public @interface TestOptions {
enum Option {
BAR,
BAZ,
}
}
@Test
public void DoTest() {
Assert.assertNotEquals(Option.BAR, Option.BAZ);
}
}
但是,在最后一次导入(foo.BadImportsTest.TestOptions.Option
)的原始顺序中,它会进行编译。
我试过检查规格。这似乎是单一类型导入声明,但我对section 7.5.1的解读并没有解释上述行为。我正在当前文件中导入嵌套类型,但是,它会导致出现问题,因为它似乎应该在查找Option
时出错:
如果在包含
import
声明的编译单元中声明了single-type-import声明导入的类型,则忽略import
声明。
我通过Maven和IntelliJ IDEA测试了编译,在所有情况下都针对Java 8。
我确实找到了Order of imports seems to matter for compilation to succeed?但是这指向了一个似乎不适用的编译器错误,因为它涉及static
导入而我没有使用静态导入。此外,它在Java 8中标记为已修复,我使用的是Java 8。
答案 0 :(得分:2)
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6391197
以下代码仍然给我一个错误。
package test;
import static test.Outer.Inner.CONST;
import java.util.Iterator;
class Outer {
interface Inner extends Iterator {
static String CONST = "CONST";
}
}
该错误仍然存在于java 8中,至少在我的编译器版本中:javac 1.8.0_121。
Java 8相关错误:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8148472
所以这是一个错误,请寻找解决方法。
答案 1 :(得分:0)
我的猜测是它无法找到保留导入,因为导入'foo.BadImportsTest.TestOptions.Option;'从它所在的同一个类中导入一些东西。通过先放入该导入,导致导入过程失败,然后才能导入任何东西。通过把它放在最后,它的失败不能阻止任何其他导入失败,因为它们已经被输入,因此如果你把它放在首位,就不会产生你收到的错误。