泛型(2)

news/2024/12/24 1:46:16 标签: java

泛型(2) 

1、泛型在继承上的体现

如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G并不是G的子类型!

比如:String是Object的子类,但是List并不是List的子类。

class A <T> extends superA<String>{......}

只有泛型类相同时,父类与子类之间才能体现继承关系。

例如:父类SuperA<String>与子类A<String>之间存在继承关系,类A的实例对象可以被SuperA引用体现多态性;但SuperB<Object>与B<String>之间没有继承关系。

2、通配符的使用

当我们声明一个变量/形参时,这个变量/形参的类型是一个泛型类或泛型接口,例如:Comparator类型,但是我们仍然无法确定这个泛型类或泛型接口的类型变量的具体类型,此时我们考虑使用类型通配符 ? 。

1 通配符的理解

使用类型通配符:?

比如:List<?>Map<?,?>

 List<?>List<String>List<Object>等各种泛型List的父类

2 通配符的读与写

写操作:

将任意元素加入到其中不是类型安全的:

Collection<?> c = new ArrayList<String>();

c.add(new Object()); // 编译时错误

因为我们不知道c的元素类型,我们不能向其中添加对象。add方法有类型参数E作为集合的元素类型。我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。

唯一可以插入的元素是null,因为它是所有引用类型的默认值。

读操作:

另一方面,读取List<?>的对象list中的元素时,永远是安全的,因为不管 list 的真实类型是什么,它包含的都是Object。

java">@Test
public void test1(){
    List<?>list = null;//通配符‘?’不确定类型
    List<String> list1 =Arrays.asList(new String[]{"Qum","Dit","TuSu"});
    list = list1;
    Object obj = list.get(0);//get得到Object的接收值
    System.out.println(obj);//可以读取,不能写入
}

总结:使用通配符的集合,可读不可写。其他泛型类型的集合可以赋值给使用通配符的集合。

java">@Test
public void test4(){
    List<?>list = new ArrayList<>();
    List <String> list1 = null;
    List <Integer>list2 = null;
    
    list = list1;//使用通配符作为泛型类型可以传入任意泛型类型的集合元素。
    list = list2;
    //list1 = list2;编译时错误,泛型类型不同不能传入集合元素。
}

3 使用注意点

注意点1:编译错误:不能用在泛型方法声明,返回值类型前面<>不能使用?

public static <?> void test(ArrayList<?> list){
}

注意点2:编译错误:不能用在泛型类的声明

class GenericTypeClass<?>{
}

注意点3:编译错误:不能用在创建对象上,右边属于创建集合对象

ArrayList<?> list2 = new ArrayList<?>();

4 有限制的通配符

  • <?>
    • 允许所有泛型的引用调用
  • 通配符指定上限:<? extends 类/接口 >
    • 使用时指定的类型必须是继承某个类,或者实现某个接口,即<=
java">@Test
public void test2(){
    List<? extends Person> list = null;
    List<Object> list1 = null;
    List<Object> list2 = null;
    List<Person> list3 = null;
    List<Student> list4 = null;

    //list = list2;
    list = list3;//extend,继承于。 Person、Person的子类可以传入
    list = list4;
}
  • 无法写入数据,除了null
  • 通配符指定下限:<? super 类/接口 >
    • 使用时指定的类型必须是操作的类或接口,或者是操作的类的父类或接口的父接口,即>=
java">@Test
public void test3(){
    List<? super Person> list = null;
    List<Object> list1 = null;
    List<Object> list2 = null;
    List<Person> list3 = null;
    List<Student> list4 = null;

    list = list2;
    list = list3;//super,写入父类, Person或者其父类可以传入
    //list = list4;
}
  • 可以写入Person及其子类的数据。
  • 说明:
  1.  extends Number>     //(无穷小 , Number]
    //只允许泛型为Number及Number子类的引用调用

    <? super Number>      //[Number , 无穷大)
    //只允许泛型为Number及Number父类的引用调用

    <? extends Comparable>
    //只允许泛型为实现Comparable接口的实现类的引用调用


http://www.niftyadmin.cn/n/5797207.html

相关文章

网络七层杀伤链

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&…

Linux SHELL脚本中的变量与运算

一.SHELL脚本中的变量 1.1.什么是变量 在编写程序时&#xff0c;通常会遇到被操作对象不固定的情况 我们需要用一串固定的字符来表示不固定的值这就是变量存在的根本意义 变量的实现原理就是内存存储单元的一个符号名称 1.2.变量的命名规则 变量的名称中只能包含数字、大…

QT_Demo(1)之实现多线程实现简单的电脑摄像头视频流开关

QT_Demo&#xff08;1&#xff09;之实现多线程实现简单的电脑摄像头视频流开关 使用qt中的多线程进行功能控制&#xff1a;继承QThread直接通过代码进行UI搭建简单示例使用信号与槽 1. 功能介绍 首先想搭一个界面可以交互&#xff0c;从而实现手动开关笔记本摄像头的目的 想…

C#经典算法面试题

网络上收集的一些C#经典算法面试题&#xff0c;分享给大家 # 递归算法 ## C#递归算法计算阶乘的方法 > 一个正整数的阶乘&#xff08;factorial&#xff09;是所有小于及等于该数的正整数的积&#xff0c;并且0的阶乘为1。自然数n的阶乘写作n!。1808年&#xff0c;基斯顿…

MySQL InnoDB 存储引擎详解

InnoDB 是 MySQL 中最常用、最强大的存储引擎之一&#xff0c;其支持事务、外键、行级锁等特性&#xff0c;非常适合对可靠性、并发性要求较高的场景。本文将详细解析 InnoDB 的核心特性、内部机制以及使用场景&#xff0c;帮助你更好地理解和优化 MySQL 数据库。 1. 为什么选择…

【C#】WebSoket 演示(使用websocket-sharp库)

Example 3服务器 Example1 客户端 示例3 此源代码片段包含了如何使用WebSocketSharp库来创建一个HTTP服务器&#xff0c;并提供WebSocket服务。 分析整个代码&#xff0c;我们可以归纳出以下关键信息&#xff1a; 导入了一系列重要的命名空间&#xff0c;包括系统配置、加密库…

【数据安全】如何保证其安全

数据安全风险 数字经济时代&#xff0c;数据已成为重要的生产要素。智慧城市、智慧政务的建设&#xff0c;正以数据为核心&#xff0c;推动城市管理的智能化和公共服务的优化。然而&#xff0c;公共数据开放共享与隐私保护之间的矛盾日益凸显&#xff0c;如何在确保数据安全的…

HTTPS如何通过CA证书实现安全通信,以及HTTPS的局限性

关键概念&#xff1a; HTTPS&#xff1a; 超文本传输安全协议&#xff0c;是HTTP的安全版本&#xff0c;通过SSL/TLS协议对数据进行加密&#xff0c;提供身份验证、数据加密和数据完整性。CA&#xff08;证书颁发机构&#xff09;&#xff1a; 受信任的第三方机构&#xff0c;…