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类型(我总有一个装你) 生产者

相关文章
|
7月前
|
安全 Java
Java之泛型使用教程
Java之泛型使用教程
451 10
|
9月前
|
安全 Java API
在Java中识别泛型信息
以上步骤和示例代码展示了怎样在Java中获取泛型类、泛型方法和泛型字段的类型参数信息。这些方法利用Java的反射API来绕过类型擦除的限制并访问运行时的类型信息。这对于在运行时进行类型安全的操作是很有帮助的,比如在创建类型安全的集合或者其他复杂数据结构时处理泛型。注意,过度使用反射可能会导致代码难以理解和维护,因此应该在确有必要时才使用反射来获取泛型信息。
312 11
|
安全 Java 开发者
Java 泛型中的通配符 T,E,K,V,?有去搞清楚吗?
本文介绍了Java泛型及其通配符的使用方法与作用。泛型是JDK5引入的特性,提供编译时类型安全检测,避免运行时类型转换异常。文中详细解析了常见通配符T、E、K、V、?的含义及应用场景,如无界通配符`&lt;?&gt;`、上界通配符`&lt;? extends T&gt;`和下界通配符`&lt;? super T&gt;`。通过代码示例,展示了泛型在类型安全、消除强制转换、代码复用和增强可读性等方面的优势。最后强调深入理解技术原理的重要性,以提升开发能力。
491 0
|
Java
Java 面向对象编程的三大法宝:封装、继承与多态
本文介绍了Java面向对象编程中的三大核心概念:封装、继承和多态。
735 15
|
Java
在Java中,接口之间可以继承吗?
接口继承是一种重要的机制,它允许一个接口从另一个或多个接口继承方法和常量。
1303 60
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
452 2
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
275 2
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
328 3