在Java中,泛型是不变的吗? [英] In Java Generics are invariant?

查看:80
本文介绍了在Java中,泛型是不变的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编译以下代码失败:

public static void swap(List<?> list, int i, int j) {
       list.set(i, list.set(j, list.get(i)));
}

喜欢:

Swap.java:5: set(int,capture#282 of ?) in List<capture#282 of ?> cannot be applied to (int,Object)
           list.set(i, list.set(j, list.get(i)));

但是,如果我这样做:

public static void swap(List<?> list, int i, int j) {
       swapHelper(list, i, j);
}

private static <E> void swapHelper(List<E> list, int i, int j) { list.set(i, list.set(j, list.get(i)));
}

它运行良好.

但是我在这里有一个基本的疑问.据说泛型是不变的,所以List<String>不是List<Object>的子类型,对吧?

But I have a basic doubt here. Generics are said to be invariant, so List<String> is not subtype of List<Object>, right?

如果是这种情况,那么采用上述方法怎么能将List<?>传递给List<E>?如何运作?

If that is the case, then how come in the above method, we are able to pass List<?> to List<E>? How does this works?

推荐答案

答案是通配符.

List<?>List<Object>不同 尽管java假定这两个都是Object的集合,但前者将匹配任何其他List<T>的类型,而后者将不匹配除List<Object>之外的任何List<T>的类型.

List<?> is not the same as List<Object> while java assumes both are collections of Object, the former will match the type of any other List<T>, while the latter will not match the type of any List<T> besides List<Object>.

示例:

public void doSomething(List<Object> list);

此函数仅接受List<Object>作为其参数.但是:

This function will accept only List<Object> as it's parameter. However this:

public void doSomething(List<?> list);

将接受任何List<T>作为其参数.

will accept any List<T> as it's parameter.

当与通用约束一起使用时,这可能非常有用. .例如,如果您想编写一个处理数字(Integer s,Float s等)的函数,则可以:

This can be extremely useful when used with generic constraints. For instance if you'd like to write a function that manipulates numbers (Integers, Floats, etc.) you could:

public void doSomethingToNumbers(List<? extends Number> numbers) { ... }

这篇关于在Java中,泛型是不变的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆