首页 > 解决方案 > Java 泛型,类型丢失

问题描述

以下示例虽然看似正确,但无法编译(Eclipse Neon 3、Java 1.8):

class Test {    

    public static class SomeForm<IF extends SomeForm<IF>> {

    }

    public static class BaseFF<IF extends SomeForm<IF>> {

    }

    public static class AuxFF<IF extends SomeForm<IF>>
            extends BaseFF<IF> {

    }

    public interface Interface<IF extends SomeForm<IF>, FF extends BaseFF<IF>> {
        FF getFF1();        
    }

    public static class ZBaseUnit<IF extends SomeForm<IF>, FF extends BaseFF<IF>>
            implements Interface<IF, FF> {

        @Override
        public FF getFF1() {
            return null;
        }

    }

    public static class ZMyUnit<IF extends SomeForm<IF>, FF extends AuxFF<IF>>
            extends ZBaseUnit<IF, FF> {

    }

    public static class ZMyCheck<IF extends SomeForm<IF>, U extends ZMyUnit<IF, ?>> {
        U unit;

        void f() {
            BaseFF<IF> ff1 = unit.getFF1();
        }

    }

}

Eclipse 说(在 f() 方法内的行上):

“类型不匹配:无法从 capture#2-of ? 转换为 Test.BaseFF”。

但是,如果我从接口 Interface(以及 ZBaseUnit 类中的 @Override 注释)中删除方法 getFF1,它就会编译。这背后有什么逻辑吗?直观上看,传给Interface的FF好像和传给ZBaseUnit的FF是一样的,所以应该没有区别……

此外,如果我在 ZMyUnit 中添加该方法,也不会出现错误:

void f() {
    BaseFF<IF> ff1 = getFF1();
}

任何帮助,将不胜感激!

标签: javaeclipsegenericscompiler-errors

解决方案


如果您将此验证码添加到您的课程

public static class GF extends SomeForm<GF> {
}

public static void main(String[] args) {
    ZMyCheck<GF, ZMyUnit<GF, AuxFF<GF>>> z = new ZMyCheck<>();
    z.unit = new ZMyUnit<>();
    z.f();
    System.out.println("OK");
}

并使用标准的 JDK 命令行工具(javacjava),然后代码将编译并成功运行。如果您使用 NetBeans 也是如此(我无意以任何方式推广 NetBeans)。

因此,问题是特定于 Eclipse 的。Eclipse 有自己的内置编译器,您似乎发现了它的一个弱点(也许您需要提交错误报告)。无法确定通配符?实际上是指扩展的类型AuxFF<IF>(因此是BaseFF<IF>)。您需要明确指出这一点:

public static class ZMyCheck<IF extends SomeForm<IF>,
    U extends ZMyUnit<IF, ? extends AuxFF<IF>>> {...}

然后一切都将编译并顺利运行。


推荐阅读