导入的类扩展第三方库

时间:2018-04-16 14:17:52

标签: java inheritance static-import ecj

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

  1. external-lib:提供抽象类

    public abstract class AbstractExternal {}
    
  2. my-lib-A:提供课程

    public class ClassA extends AbstractExternal {
        public static final String FOO = "foo";
    }
    

    external-lib位于my-lib-A的类路径中。

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

    import static ClassA.FOO;
    public class ClassB {
        private String foo = FOO;
    }
    

    my-lib-A位于my-lib-B的类路径中,但external-lib不在。

  4. 问题: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;
    }
    

    编译器很高兴。

    然而(2),当添加第二个抽象时,两个my-lib-A就像

    public class AbstractClassA extends AbstractExternal {}
    

    public class ClassA extends AbstractClassA {
        public static final String FOO = "foo";
    }
    

    上面示例中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与ECJ同步,并且能够在静态导入失败时编译ClassB中的正常导入和类访问。

1 个答案:

答案 0 :(得分:2)

理想情况下,Ecj"不应该"#34;报告此错误。我提交Bug 533890来跟踪此事。

此消息的所有错误背后的共同主题(" ...无法解决。它是间接引用的......")之间存在冲突:

  1. 想要了解所有相关类和
  2. 的完整语义分析
  3. 如果构建路径不包含当前类(间接)所依赖的所有类,则需要弹性。
  4. 显然,JLS没有说明编译器应该如何处理不完整的构建路径,但为了方便用户,如果语义分析可以避免查看某些间接依赖,则不应报告错误

    在确实可以避免的地方和时间需要根据具体情况进行检查(并实施),但是给定的示例可能符合可以可以避免的情况。 / p>

    在解决此问题之前,可以通过external-lib my-lib-B显示问题来避免此问题(例如,使用项目依赖项)。在像OSGi或JPMS这样的模块系统中,让my-lib-A"再出口"实际上是个好主意。它的依赖项external-lib,因为它的API类ClassA "不完整"对于无法查看AbstractExternal

    的客户