【问题标题】:Understanding Java Generics <T extends Class> and <? extends Class>理解 Java 泛型 <T extends Class> 和 <?扩展类>
【发布时间】:2017-05-21 21:36:01
【问题描述】:

这可能是一个愚蠢的问题,所以请原谅我的无知。

假设我有一堂课:

public class Foo<T extends Base> implements Bar<T> {
    private Bar<T> wrapped;
    public void setWrapped(Bar<T> input) {
        wrapped = input;
    }
}

如果我调用它:

//Lets just assume methods getNewVal and getFoo exist
Bar<? extends Base> val = getNewVal();
Foo<? extends Base> foo = getFoo();
foo.setWrapped(val);

编译器说 foo.execute(val) 是一个错误。带有类似 方法 setWrapped(Bar) 的消息,类型为 Foo 不适用于参数 (Bar)

如果我尝试将 Foo 更改为

public class Foo<T extends Base> implements Bar<T> {
    private Bar<T> wrapped;
    public void setWrapped(Bar<? extends Base> input) {
        wrapped = input;
    }
}

foo.setWrapped(val) 的调用不再出错。取而代之的是 wrapped = input 是一条错误消息,类似于 Type mismatch: cannot convert from Bar 扩展到 Bar

我做错了什么?有没有办法让编译器在没有强制转换的情况下接受这样的调用?

【问题讨论】:

  • 那是因为??不一样。编译器无法验证Bar&lt;? extends Base&gt; 中的? 是否与Foo&lt;? extends Base&gt; 中的? 相同,因此它们不兼容。
  • 几乎没有办法使用通配符作为返回类型,这就是您在第二个代码示例中所做的。参考文献PECS stackoverflow.com/questions/2723397/… 这些通配符是为了让泛型更容易与方法参数一起使用,而不是返回类型。
  • 示例:getNewVal() 返回 Bar&lt;HomeBase&gt;getFoo() 返回 Foo&lt;ThirdBase&gt;。这对前两个语句完全有效,但不适用于setWrapped()
  • 我们可以得到一些更具体的代码吗?
  • 谢谢安德烈亚斯。我明白为什么它现在不能那样工作了。干杯!

标签: java generics


【解决方案1】:

看起来你想要的

public class Foo {
    private Bar<? extends Base> wrapped;
    public void setWrapped(Bar<? extends Base> input) {
        wrapped = input;
    }
}

目前尚不清楚Bar 接口Foo 需要实现什么,以及为什么Foo 应该有一个Bar 以及一个Bar

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 2015-06-14
    • 1970-01-01
    • 2020-08-03
    • 2021-12-18
    • 2023-03-15
    • 2011-05-26
    • 2023-02-02
    相关资源
    最近更新 更多