Java 泛型方法类型推断的混乱

J R*_*J R 2 java type-inference wildcard generic-type-argument

示例方法如下:

static <T> void doSomething(List<? super T> list1, List<? extends T> list2) { }
Run Code Online (Sandbox Code Playgroud)

我想知道在这种情况下会通过什么逻辑推断出什么类型。假设我这样调用这个方法:

doSomething(new ArrayList<Object>(), new ArrayList<String>());
Run Code Online (Sandbox Code Playgroud)

T类型会计算为Object还是String吗?

das*_*ght 6

此调用不绑定T到特定类。Java 不需要知道确切的信息,T因为泛型的类型擦除实现。只要您传递的类型与声明一致,代码就应该可以编译;就您而言,Object和的列表String与声明一致。

让我们稍微扩展一下您的代码,以便我们可以强制绑定T到特定类型。也许最简单的方法是传递Class<T>,如下所示:

static <T> void doSomething(List<? super T> list1, List<? extends T> list2, Class<T> cl) {
    System.out.println(cl);
}
Run Code Online (Sandbox Code Playgroud)

现在让我们尝试使用doSomethingString.classwith进行调用Object.class

doSomething(new ArrayList<Object>(), new ArrayList<String>(), Object.class);
doSomething(new ArrayList<Object>(), new ArrayList<String>(), String.class);
Run Code Online (Sandbox Code Playgroud)

两个调用都成功编译,产生输出

class java.lang.Object
class java.lang.String
Run Code Online (Sandbox Code Playgroud)

ideone 上的演示。