您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
在Java中,泛型的协变和逆变是通过使用通配符?
和extends
、super
关键字来实现的。协变(covariance)允许你使用一个比原始指定的派生类型更具体的类型,而逆变(contravariance)允许你使用一个比原始指定的派生类型更泛化的类型。
协变允许你使用一个更具体的类型来替换泛型参数。在Java中,这可以通过使用通配符? extends T
来实现。这意味着你可以读取数据,但不能写入数据(除了null)。
public class CovarianceExample {
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3);
List<Number> numbers = integers; // 协变
// numbers.add(4); // 编译错误,不能写入数据
Number number = numbers.get(0); // 读取数据是允许的
}
}
逆变允许你使用一个更泛化的类型来替换泛型参数。在Java中,这可以通过使用通配符? super T
来实现。这意味着你可以写入数据,但不能保证读取的数据类型安全(只能保证它是T或T的父类)。
public class ContravarianceExample {
public static void main(String[] args) {
List<Number> numbers = new ArrayList<>();
List<Object> objects = numbers; // 逆变
objects.add(new Object()); // 写入数据是允许的
Number number = numbers.get(0); // 读取数据是允许的,但可能不是最具体的类型
}
}
使用通配符?
时,有一些限制:
new List<?>()
是不允许的。List<?> list = new ArrayList<Integer>();
是允许的,但List<Integer> list = new ArrayList<?>();
是不允许的。泛型方法也可以使用协变和逆变:
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (T t : src) {
dest.add(t);
}
}
在这个例子中,copy
方法的第一个参数是逆变的,因为它接受T
或T
的父类的列表。第二个参数是协变的,因为它接受T
或T
的子类的列表。
通过这种方式,Java的泛型系统提供了灵活的类型安全机制,允许在不同的场景下重用代码,同时保持类型的一致性和安全性。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。