Java泛型的继承和通配符

简介: Java泛型的继承和通配符

泛型的继承和通配符

继承

两个容器所容纳的类类型是有子类父类的关系的

但是容器之间没有

反证法:

假设做法成立

ArrayList<Object> list1 = null;
 ArrayList<String> list2 - new ArrayList<>();

list1=list2

list 指向list2的容器实例

list1.add(123)可以成立,明显标注<String>后是不行的

所以

  1. 类SuperA是类A的父类,则G<SuperA>G<A>是并列关系没有子父关系
  2. 类SuperA是类A的父类或接口,SuperA<G>与A<6>的关系:SuperA<6>与A<G>有继承或实现的关系。即A<G>的实例可以赋值给SuperA<G>类型的引用(或变量)
    比如: List<String>ArrayList<String>

通配符

  1. 通配符:?
List<?> list = null;
List<Object> list1 = null;List<String> list2 = null;
list = list1;
list = list2;
  1. 使用说明:
  2. 读写数据的特点(以集合为例说明)
    只能读(Object类型),不能写,因为类型是不确定的
  3. 有限制条件的通配符
    `List<? extends A> :List <? super A> :``
  4. 有限制条件的统配符的读写操作(难、了解)

理解了一下传过来 的function 参数是T 的父类, 返回值随意

调用这个函数的时候 参数只能是T的子类,接受返回值的类型只能是U和U的父类

? super Type``

? super TypeJava泛型中是一个下界通配符(Lower Bounded Wildcard)。它的主要使用场景涉及到在泛型集合中进行写入操作时的类型安全性和灵活性。以下是 ? super Type 的一些典型使用场景:

1. 写入操作的灵活性和安全性

当你需要向泛型集合中添加数据时,使用 ? super Type 可以提供更大的灵活性。例如,如果你有一个方法,需要向一个泛型集合中添加特定类型的对象,你可以使用 ? super Type 来确保集合至少可以接受这个类型或其父类型:

public void addNumbers(List<? super Integer> list) {
    list.add(new Integer(1)); // 安全
    // 可以添加 Integer 或其子类型
}

在这个例子中,列表可以是 Integer 类型的,也可以是任何 Integer 的超类(如 NumberObject)的列表。

2. 反转依赖性

在“生产者-消费者”模型中,使用 ? super Type 可以作为生产者(写入),? extends Type 作为消费者(读取)。这符合PECS(Producer-Extends, Consumer-Super)原则:

  • 生产者使用 ? extends Type,因为它们产生的数据必须至少是 Type
  • 消费者使用 ? super Type,因为它们消费的数据可以是 Type 或其任何父类型。
3. API设计中的通用性

当设计泛型API时,使用 ? super Type 可以让你的API在处理写入操作时更加灵活。例如,一个可以接受多种类型对象的通用添加方法:

public void addToCollection(Collection<? super MyType> collection, MyType item) {
    collection.add(item);
}

这样的方法可以接受 MyType 的任何超类型的集合。

4. 提供更宽松的类型限制

在某些情况下,你可能需要放宽对传入对象类型的限制。使用 ? super Type 允许更宽松的类型限制,使得代码可以接受更多种类的参数。

总结

? super Type 的使用主要是为了提高在泛型编程中对集合的写入操作的灵活性和

安全性。它允许你在泛型方法或类中指定参数类型可以是特定类型的任何超类型,这在设计具有广泛兼容性的API、处理多态集合的写入操作,以及实现符合PECS原则的代码时尤其有用。通过这种方式,你可以编写出更加灵活、更具适应性的泛型代码。

? super Type> 在消费此对象的时候,可以将此Type引用各种子类类型(我能往你里面随便装) 消费者

? extends Type 中可以用Type类型及其去接受Type类型(我总有一个装你) 生产者

相关文章
|
24天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
19 3
|
24天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
33 2
|
24天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
28 2
|
23天前
|
Java API
[Java]泛型
本文详细介绍了Java泛型的相关概念和使用方法,包括类型判断、继承泛型类或实现泛型接口、泛型通配符、泛型方法、泛型上下边界、静态方法中使用泛型等内容。作者通过多个示例和测试代码,深入浅出地解释了泛型的原理和应用场景,帮助读者更好地理解和掌握Java泛型的使用技巧。文章还探讨了一些常见的疑惑和误区,如泛型擦除和基本数据类型数组的使用限制。最后,作者强调了泛型在实际开发中的重要性和应用价值。
19 0
[Java]泛型
|
24天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
28 1
|
1月前
|
存储 安全 Java
🌱Java零基础 - 泛型详解
【10月更文挑战第7天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
11 1
|
1月前
|
Java 测试技术 编译器
Java零基础-继承详解!
【10月更文挑战第4天】Java零基础教学篇,手把手实践教学!
34 2
|
1月前
|
存储 Java 编译器
Java集合定义其泛型
Java集合定义其泛型
18 1
|
1月前
|
Java 测试技术 编译器
Java零基础-继承详解!
【10月更文挑战第6天】Java零基础教学篇,手把手实践教学!
22 0
|
1月前
|
安全 Java 编译器
Java基础-泛型机制
Java基础-泛型机制
16 0