有什么区别?和 Java 泛型中的对象?

2022-08-31 07:28:50

我正在使用Eclipse来帮助我清理一些代码以正确使用Java泛型。大多数时候,它在推断类型方面做得很好,但在某些情况下,推断的类型必须尽可能通用:Object。但是Eclipse似乎给了我一个选择,可以在一种类型的对象和一种“?”类型之间进行选择。

那么两者之间有什么区别:

HashMap<String, ?> hash1;

HashMap<String, Object> hash2;

答案 1

匹配但不是 的实例。假设你想写一个接受从s到任何东西的映射的方法:如果你愿意写HashMap<String, String>Map<String, ?>Map<String, Object>String

public void foobar(Map<String, Object> ms) {
    ...
}

您无法提供 .如果你写HashMap<String, String>

public void foobar(Map<String, ?> ms) {
    ...
}

它的工作原理!

在Java的泛型中有时被误解的一件事是,它不是的子类型。(但实际上它是 的子类型,这是泛型和数组不能很好地混合的原因之一。(Java中的数组是协变的,泛型不是,它们是不变的))。List<String>List<Object>String[]Object[]

示例:如果你想编写一个接受 s 的 s 和 的子类型的方法,你可以这样写ListInputStreamInputStream

public void foobar(List<? extends InputStream> ms) {
    ...
}

顺便说一句:Joshua Bloch的 Effective Java是一个很好的资源,当你想了解Java中不那么简单的东西时。(你上面的问题在书中也有很好的介绍。


答案 2

思考这个问题的另一种方法是

HashMap<String, ?> hash1;

等效于

HashMap<String, ? extends Object> hash1;

将这些知识与 Java 泛型和集合中 (2.4) 中的“获取和放置原则”结合使用:

获取和放置原则:当您仅从结构中获取值时使用扩展通配符,在仅将值放入结构时使用超级通配符,并且在同时获取和放置时不使用通配符。

希望通配符可能开始更有意义。


推荐