【问题标题】:What difference between <T extends Foo> and <? extends Foo>?<T extends Foo> 和 < 之间有什么区别?扩展 Foo>?
【发布时间】:2021-11-20 09:20:17
【问题描述】:

我有以下代码:

abstract public class Base {
    private static final HashMap<Integer, ? extends Base> hashMap = new HashMap<>();

    public static <T extends Base> void put(Integer key, T val) {
        hashMap.put(key, val);
    }

    public static <T extends Base> T get(Integer key) {
        return hashMap.get(key);
    }
}

所以,我在 Base.put() 方法中得到了不兼容的类型:&lt;T extends Base&gt;&lt;? extends Base&gt;

有什么区别以及如何正确重写该代码?

【问题讨论】:

  • 你不能就这样。通配符泛型意味着“这些范围内的某些特定类型,但我不知道是什么”。 ? 的意思是“我也不在乎”。但它仍然是单一的特定类型。您的 put 方法允许调用者指定类型 - 因此编译器无法保证类型安全。删除泛型,全部改成Base,这样就可以了。
  • @BoristheSpider 我只是试图用泛型阐明类型继承,但这不是必需的,我明白了。

标签: java generics


【解决方案1】:

很简单:

? - 是一个通配符

T - 是一个泛型类型

它们相似但不同。如果你想强制类型,你不能使用通配符。你必须使用泛型

示例

public <T extends Number> void copy(List<T> dest,List<T> src){
    //code
}

上面的代码将能够将列表从 src 复制到 dest。 src 和 dest 都具有相同的泛型类型,因此复制每个元素是安全的。

public void copy(List<? extends Number> dest, List<? extends Number> src){
    //code
}

上面的代码不是很好。 dest 可以是 ListInteger> 类型,而 src 可以是 ListDouble

类型

希望对你有帮助~

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-06
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 2016-12-01
    • 2015-03-08
    相关资源
    最近更新 更多