相关疑难解决方法(0)

Java Generics Puzzler,扩展一个类并使用通配符

我一直在打击这个问题一段时间,并认为可能会有一些新鲜的眼睛看到这个问题; 谢谢你的时间.

import java.util.*;

class Tbin<T> extends ArrayList<T> {}
class TbinList<T> extends ArrayList<Tbin<T>> {}

class Base {}
class Derived extends Base {}

public class Test {
  public static void main(String[] args) {
    ArrayList<Tbin<? extends Base>> test = new ArrayList<>();
    test.add(new Tbin<Derived>());

    TbinList<? extends Base> test2 = new TbinList<>();
    test2.add(new Tbin<Derived>());
  }
}
Run Code Online (Sandbox Code Playgroud)

使用Java 8.在我看来,直接创建容器test就等同于容器test2,但编译器说:

Test.java:15: error: no suitable method found for add(Tbin<Derived>)
    test2.add(new Tbin<Derived>());
         ^
Run Code Online (Sandbox Code Playgroud)

我怎么写Tbin,TbinList所以最后一行是可以接受的?

请注意,我实际上将添加类型Tbins,这就是我Tbin<Derived>在最后一行中指定的原因.

java generics bounded-wildcard

51
推荐指数
3
解决办法
1592
查看次数

捕获Java中的转换问题,JLS的WRT协调和实际的JDK行为

给出以下两个类定义:

class C1<T extends C1<T>> {}

class C2<U> extends C1<C2<U>> {}
Run Code Online (Sandbox Code Playgroud)

请考虑以下类型声明:

C1<? extends C2<String>> c;
Run Code Online (Sandbox Code Playgroud)

这将编译在JDK-8u45好的,但如果我们考察了采集转换规范,它出现(我)这个声明应该导致编译时错误.

特别是,新类型变量捕获的上限由下式T#1给出glb(Bi, Ui[A1:=S1,...,An:=Sn]),在这种情况下,Bi解析为通配符绑定C2<String>Ui[A1:=S1,...,An:=Sn]解析为C1<T#1>.

由此,glb(C2<?>, C1<T#1>)解析为交叉点型C2<String> & C1<T#1>,这是无效的,因为C2<String>C1<T#1>都是类类型,而不是接口类型,但其中没有一个是另一个的子类型.

这种(明显的)规则违规可能在交集类型本身的定义中更加清晰.

我确定这不是一个错误,我只是在某个地方犯了一些简单的错误...... 如果它是一个bug,我希望它可以被认为是JLS中的错误而不是JDK,这样我可以期望能够安全地模拟行为......

谢谢你的帮助!

编辑:有Radiodef昨天交谈后我说服自己,这个问题(或者看它单程至少)是C2<String> 能有效地被认为是作为一个亚型C1<T#1>,因为T#1只能永远被满足C2<String>,因此可被认为是相同的,但是遏制和子类型规则并没有像写的那样理解这种关系,因此JLS不会识别子类型并且应该失败......

但是,如果你采取稍微复杂的情况C1<? extends C2<?>> d;,那就更棘手了.问题是类似的,但是形成捕获上限的交集类型出现了C2<?> & C1<T#2>,似乎没有解决方案可以通过与上述相同的推理得出.

java generics compiler-errors wildcard

15
推荐指数
1
解决办法
329
查看次数