当导入的类扩展第三方库时,Java导入静态失败

Hen*_*reu 6 java inheritance static-import ecj

问题设置包含三个java库(为了便于阅读,我删除了所有软件包名称,到处都使用了完整的限定名称):

  1. external-lib:提供抽象类

    public abstract class AbstractExternal {}
    
    Run Code Online (Sandbox Code Playgroud)
  2. my-lib-A:提供课程

    public class ClassA extends AbstractExternal {
        public static final String FOO = "foo";
    }
    
    Run Code Online (Sandbox Code Playgroud)

    external-lib 在my-lib-A的类路径中.

  3. my-lib-B静态地从ClassA导入FOO:

    import static ClassA.FOO;
    public class ClassB {
        private String foo = FOO;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    my-lib-A在my-lib-B的类路径中,但external-lib不是.

问题:该import static行产生以下错误:

The type AbstractExternal cannot be resolved. It is indirectly referenced from required .class files.

但是(1),将ClassB修改为

import ClassA;
public class ClassB {
    private String foo = ClassA.FOO;
}
Run Code Online (Sandbox Code Playgroud)

编译器很高兴.

但是(2),当添加第二个抽象时,两个my-lib-A就好了

public class AbstractClassA extends AbstractExternal {}
Run Code Online (Sandbox Code Playgroud)

public class ClassA extends AbstractClassA {
    public static final String FOO = "foo";
}
Run Code Online (Sandbox Code Playgroud)

上例中的ClassA.FOO的静态导入有效.

问题1:为什么import static ClassA.FOO失败而import ClassAClassA.FOO作品?

问题2:为什么import static ClassA.FOO它从my-lib-A扩展另一个类然后扩展AbstractExternal?

编辑:重要信息:有问题的编译器是Eclipse Compiler for Java(ECJ).

编辑2:javac的是同步与欧洲法院,并能同时静态导入失败来编译ClassB的正常的货物类访问.

Ste*_*ann 2

理想情况下,Ecj“不应该”报告此错误。我提交了Bug 533890来跟踪此问题。

此消息的所有错误背后的共同主题(“...无法解析。它被间接引用...”)是以下之间的冲突:

  1. 想要完整的语义分析,了解所有相关的类和
  2. 如果构建路径不包含当前类(间接)依赖的所有类,则需要弹性。

显然,JLS 没有指定编译器应如何处理不完整的构建路径,但为了方便用户,如果语义分析可以避免查看某些间接依赖项,则不应报告错误。

何时何地确实可以避免这种情况,需要根据具体情况进行检查(和实施),但给出的示例可能符合可以避免的情况

external-lib在这个问题得到解决之前,可以通过使其可见my-lib-B(例如,使用项目依赖项)来避免该问题。在像 OSGi 或 JPMS 这样的模块系统中,让my-lib-A“重新导出”它的依赖项实际上可能是一个好主意external-lib,因为它的 API 类对于无法看到的客户端来说ClassA AbstractExternal“不完整的” 。