甚至在不需要时也需要通用参数?

Jos*_* M. 1 java generics java-8

class Thing<T> {
    public Map<String, List<String>> getData() { ... }
}

class Thingamajig {
    void doStuff() {
        Thing myThing = ...;
        List<String> data = myThing.getData().get("some_key");
    }
}
Run Code Online (Sandbox Code Playgroud)

的调用myThing.getData()产生以下错误:

不兼容的类型:java.lang.Object无法转换为java.util.List

通过为Thing实例提供通用参数可以解决此问题:

void doStuff() {
    Thing<?> myThing = ...;
    List<String> data = myThing.getData().get("some_key");
}
Run Code Online (Sandbox Code Playgroud)

即使是通用通配符也可以解决此问题。对我来说,这是没有意义的,因为getData()甚至没有引用泛型类型参数。

Jon*_*eet 7

当您使用原始类型Thing)时,您最终会擦除该类型-实际上,仿佛根本就没有泛型。(原始类型的存在主要是为了允许在存在泛型之前编写的代码仍然可以使用。)这在JLS的4.8节中进行了描述。

因此原始类型Thing如下所示:

class Thing {
    public Map getData() { ... }
}
Run Code Online (Sandbox Code Playgroud)

因此,的返回类型为getData原始Map类型,然后Map.get()返回Object

使用通配符有效地告诉编译器“我了解泛型,并希望继续将类型与泛型一起使用;我只是不在乎type参数。”

  • @Slaw支持原始类型的整个想法是支持前泛型代码。因此,如果原始类型出现在某些代码中,则将再现与引入泛型之前相同的行为。但这并不能满足所有构造的需要,并且比解决旧代码的问题要对新代码造成更大的伤害。是的,为什么新代码的作者必须处理提供超过15年历史的代码的兼容性功能,这是无法理解的,但这就是它的设计方式。处理它的最佳方法是启用所有编译器警告,并在各处避免使用原始类型。 (4认同)