6

这是我的课:

package pepelu;

import pepelu.ImportTest.InnerClass.InnerEnum;
import javax.annotation.Resource;

public class ImportTest {
    @Resource
    public static class InnerClass {
        public enum InnerEnum {
            A
        }
    }

    public static void main(String[] args) {
        System.out.println(InnerEnum.A);
    }
}

当我使用maven构建时,会报编译错误:

mvn clean compile

[错误] /Users/finup/Desktop/a/importtest/src/main/java/pepelu/ImportTest.java:[8,6] 找不到符号

将导入顺序更改为:

import javax.annotation.Resource;
import pepelu.ImportTest.InnerClass.InnerEnum;

我得到了一个成功的 Maven 构建。

我搜索了文档,但找不到对此的解释。

谁能解释一下在这种情况下导入是如何工作的?

4

1 回答 1

5

我猜原因是“循环”依赖:您在定义它的同一个文件/类中X导入了一些元素。

意义:

import pepelu.ImportTest.InnerClass.InnerEnum;

实际上是指同一文件中的以下代码:

public static class InnerClass {
    public enum InnerEnum {

这意味着:对于编译器,为了处理该导入,它必须查看同一文件中类的主体。

似乎 javac “立即”这样做了。含义:它开始读取导入语句,并从同一个类导入使其“暂停”查看导入,但检查以下类定义。

猜猜看:该类定义使用了另一个导入。为了“处理”该枚举的定义,编译器需要了解 @Resource 注释的位置/内容。但它还不知道注释(因为编译器还没有看到导入)。

当您更改顺序时,编译器会了解类定义中的 @Resource 用法。

当然:真正的答案不是重新订购进口商品。真正的答案是不要从 import 语句之后的类中导入某些东西。这样做绝对没有意义。

编辑,鉴于 OP 关于这如何在Redisson中工作的评论:老实说,我不知道。这可能取决于该类的编译方式。也许这样的代码适用于更新(或旧)版本的 javac,也许这适用于特定版本的 eclipse 或 intellij 或 xyz 编译器。

含义:我向您解释了您遇到此问题的原因。这并不意味着任何编译器都必须遇到同样的问题。

于 2018-08-16T09:23:18.593 回答