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

Java 为什么重新排列导入会导致编译失败?,java,import,Java,Import,为什么重新安排Java导入会导致代码不再编译 我认为Java导入的顺序对代码的语义并不重要,这使它成为一个安全的操作。编辑器使组织/优化/重新排列Java导入语句变得非常容易,一些样式检查/分析工具将强制执行命令。我没有成功地在网上找到提到重新安排进口的危险的帖子。然而,我现在遇到了一个例子,重新排列导入会导致代码中断 以下代码不会编译,表示找不到符号保留时间: package foo; import foo.BadImportsTest.TestOptions.Option; import j

为什么重新安排Java导入会导致代码不再编译

我认为Java导入的顺序对代码的语义并不重要,这使它成为一个安全的操作。编辑器使组织/优化/重新排列Java导入语句变得非常容易,一些样式检查/分析工具将强制执行命令。我没有成功地在网上找到提到重新安排进口的危险的帖子。然而,我现在遇到了一个例子,重新排列导入会导致代码中断

以下代码不会编译,表示找不到符号
保留时间

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.baddimportsettest.TestOptions.Option
)最后一次导入的原始顺序,它会编译

我试图检查规范。这似乎是一个单一类型的导入声明,但我对DOS的阅读并不能解释上述行为。我正在当前文件中导入嵌套类型,但是,它可能会导致查找
选项时出现错误,因为:

如果在包含
import
声明的编译单元中声明了由单一类型导入声明导入的类型,则将忽略
import
声明

我通过Maven和IntellijIDEA测试了编译,在所有情况下都以Java8为目标


我确实发现了一个编译器错误,它似乎不适用,因为它涉及到
静态导入,而我没有使用静态导入。此外,它在Java 8中被标记为固定的,我正在使用Java 8。

我的猜测是,它找不到保留导入,因为导入“foo.badImportTest.TestOptions.Option;”正在从它所在的同一类导入某些内容。通过将该导入放在第一位,会导致导入过程在任何东西可以导入之前失败。通过将其放在最后,其失败无法阻止任何其他导入失败,因为它们已被输入,因此不会产生您在将其放在第一位时收到的错误。

下面的代码仍然给我一个错误

package test;

import static test.Outer.Inner.CONST;
import java.util.Iterator;

class Outer {
  interface Inner extends Iterator {
    static String CONST = "CONST";
  }
}
这个bug仍然存在于Java8中,至少在我的编译器版本:JavaC1.8.0_121中

Java 8相关错误:


因此,这是一个bug,请着手解决。

删除
import foo.baddimportsettest.TestOptions.Option-不要尝试从您当前所在的班级导入内容!在这种情况下,我需要限定用法,然后IDE“有益地”建议我导入它:-)我想知道为什么他们说编译器需要在导入时知道类型?在我看来,我只需要知道该名称在该点上存在,并准备根据需要打开其范围、了解其类型等。这确实似乎是一个编译器错误。我尝试了Java6到Java10,我的原始示例开始使用Java9。