为什么重新安排导入会导致编译失败?

时间:2018-05-03 01:07:43

标签: java import

为什么重新安排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。

2 个答案:

答案 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;'从它所在的同一个类中导入一些东西。通过先放入该导入,导致导入过程失败,然后才能导入任何东西。通过把它放在最后,它的失败不能阻止任何其他导入失败,因为它们已经被输入,因此如果你把它放在首位,就不会产生你收到的错误。