繁体   English   中英

使用Javac 8编译代码时的Java类型错误,可在Javac 6上正常工作

[英]Java type error when compiling code with javac 8 which worked fine with javac 6

我有这个类,它是在从Java 6移植到Java 8的项目中找到的一些代码的简化:

public class Unification {

    final class Box<A> {}

    final class MyMap<A, B extends Box<? extends A>> {}

    MyMap<?, ?> getMap() {
        return new MyMap<Object, Box<Object>>();
    }

    <A, B extends Box<? extends A>> void setMap(final MyMap<A, B> m) {}

    void compileError() {
        setMap(getMap());
    }

}

这是一个很小的例子,仅用来展示问题,实际的代码更有意义。 这个问题似乎很普遍,因此是一个抽象的例子。 核心问题如下:由于某种原因,javac不想接受类型为MyMap<?, ?>的表达式作为setMap()方法的参数,尽管根据我的理解,这应该是-输入。

使用Javac 6编译代码时没有错误,但是当我使用Javac 8时却得到了这个晦涩的错误消息:

C:\System9\KWS_sparse\sourcesNG\Domain\src\uz\Unification.java (21:9) error: method setMap in class Unification cannot be applied to given types;
required: Unification.MyMap<A,B>
found: Unification.MyMap<CAP#1,CAP#2>
reason: inference variable A has incompatible bounds
equality constraints: CAP#1
lower bounds: Object
where A,B are type-variables:
A extends Object declared in method <A,B>setMap(Unification.MyMap<A,B>)
B extends Unification.Box<? extends A> declared in method <A,B>setMap(Unification.MyMap<A,B>)
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Object from capture of ?
CAP#2 extends Unification.Box<? extends CAP#1> from capture of ?

错误消息似乎表明无法为MyMap的第一个类型参数找到统一,javac无法找到与CAP#1统一的类型, CAP#1代表setMap()的实际参数中的第一个通配符参数,并且A ,它是setMap()形式参数的对应类型参数。 即使在我看来ACAP#1应该是完全不可统一的,但它们都将代表通过删除getMap()签名中的实际类型而引入的存在类型。

任何人都可以发现这里出了什么问题吗? javac 6是否错误地接受此代码? 另外,是否有一种不太侵入(与Javac 6兼容)的方法来引导Javac 8走向正确的统一?

编辑:我尝试了从stackoverflow.com/questions/23063474/中引入一个变量的建议,但这似乎无济于事,我得到了相同的编译错误。

EDIT2:阐明了示例代码的“意图”。

EDIT3:将Map重命名为MyMap ,显然定义一个自定义Map类型太混乱了。

通过引入一种中间方法,从而迫使javac分两个阶段进行类型推断,可以解决该问题。 第一种方法仅采用一个类型参数,而第二种则作为通配符。 Javac能够正确推断此方法的单一类型参数。 然后,第二个原始方法可以从提供的参数中正确推断出第二个类型参数。

public class Unification {

    final class Box<A> {}

    final class MyMap<A, B extends Box<? extends A>> {}

    MyMap<?, ?> getMap() {
        return new MyMap<Object, Box<Object>>();
    }

    <A> void setMap(final MyMap<A, ?> m) {
        doSetMap(m);
    }

    <A, B extends Box<? extends A>> void doSetMap(final MyMap<A, B> m) {}

    void worksFineNow() {
        setMap(getMap());
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM