12.Java 泛型(自定义泛型类、自定义泛型接口、自定义泛型方法、泛型的继承与通配符)

一、泛型引入

1、为什么需要泛型

传统方式存在的问题

  1. 不能对加入到集合中的数据类型进行约束

  2. 遍历时,需要进行类型转换

泛型的理解与好处

  1. 编译时能检查添加元素的类型

  2. 能减少类型转换的次数

2、泛型初体验
(1)说明
  • 这里以 Dog 类为例
ArrayList<Dog> list = new ArrayList<Dog>();
  1. 不使用泛型:放入集合时,Dog 类型会先转换为 Object 类型,取出时,需要转换为 Dog 类型

  2. 使用泛型:放入集合和取出时,不需要进行类型转换

(2)演示
package com.my.test;import java.util.ArrayList;
import java.util.Iterator;public class GenericTest {public static void main(String[] args) {ArrayList<Dog> list = new ArrayList<>();list.add(new Dog("小黄", 2));list.add(new Dog("小汪", 3));list.add(new Dog("小多", 4));System.out.println("========== 增强 for 循环遍历 ==========");for (Dog dog : list) {System.out.println(dog);}System.out.println("========== 迭代器循环遍历 ==========");Iterator<Dog> iterator = list.iterator();while (iterator.hasNext()) {Dog dog = iterator.next();System.out.println(dog);}}
}class Dog {String name;int age;public Dog(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +'}';}
}
  • 输出结果
========== 增强 for 循环遍历 ==========
Dog{name='小黄', age=2}
Dog{name='小汪', age=3}
Dog{name='小多', age=4}
========== 迭代器循环遍历 ==========
Dog{name='小黄', age=2}
Dog{name='小汪', age=3}
Dog{name='小多', age=4}
3、泛型概述
  1. 在类声明或实例化时制定好需要的具体类型

  2. 可以保证在编译时没有警告,运行时就不会产生 ClassCastException(类型转换异常)

  3. 通过标识表示类中某个属性的类型,某个方法的参数类型或返回值类型

4、泛型语法
  1. 自定义泛型类
class 【类名】 <T> {}
  1. 自定义泛型接口
class 【接口名】 <T> {}
  1. 自定泛型方法
【修饰符】 <T> 【返回数据类型】 【方法名】(【参数列表】) {}
5、注意事项
  1. T 表示类型(Type 的缩写,也可以为 K、V 等),且必须是引用类型

  2. 指定泛型具体类型后,可以传入该类型或者其子类类型

  3. 泛型的简写

// 完整写法
ArrayList<Dog> list = new ArrayList<Dog>();
// 简写
ArrayList<Dog> list = new ArrayList<>();
  1. 这样写 ArrayList<> list = new ArrayList<>();,默认指定泛型具体类型为 Object 类型

二、自定义泛型类

1、基本介绍
class 【类名】 <T> {}
2、注意事项
  1. 普通成员可以使用泛型
T t;
  1. 使用泛型的数组不能初始化,因为不能确定 T 的类型,无法开辟空间,在指定泛型的具体类型后才能初始化
// 错误写法
T arr[] = new T[];
  1. 静态成员不能使用泛型,因为静态成员与类相关,类加载时,静态成员无法确定泛型的具体类型,无法完成初始化

  2. 泛型的具体类型在创建对象时确定

  3. 创建对象时,没有指定泛型的具体类型,默认为 Object 类型

3、演示
  • CustomGenericsClassTest.java
package com.my.test;public class CustomGenericsClassTest {public static void main(String[] args) {Person<String> person1 = new Person<>("jack");Person<Integer> person2 = new Person<>(10);person1.show();person2.show();}
}class Person<T> {T t;public Person(T t) {this.t = t;}public void show() {System.out.println(this.t);}
}
  • 输出结果
jack
10

三、自定义泛型接口

1、基本介绍
class 【接口名】 <T> {}
2、注意事项
  1. 接口中静态成员不能使用泛型

  2. 接口的泛型的具体类型,在继承接口或实现接口时确定

  3. 没有指定泛型的具体类型,默认为 Object 类型

3、演示
  • CustomGenericInterfaceTest.java
package com.my.test;public class CustomGenericInterfaceTest {public static void main(String[] args) {new Student().show("jack");}
}class Student implements Person<String> {@Overridepublic void show(String s) {System.out.println(s);}
}interface Person<T> {public void show(T t);
}
  • 输出结果
jack

四、自定义泛型方法

1、基本介绍
【修饰符】 <T> 【返回数据类型】 【方法名】(【参数列表】) {}
2、注意事项
  1. 泛型方法可以定义在普通类和泛型类中

  2. 当泛型方法被调用时,泛型的具体类型被确定

  3. public void method(T t) {} 不是泛型方法,而是使用了泛型

3、演示
  • CustomGenericMethodTest.java
package com.my.test;public class CustomGenericMethodTest {public static void main(String[] args) {Cat<String> cat = new Cat<>();cat.show(10, "tom");}
}class Cat<K> {public<T> void show(T t, K k) {System.out.println(t.getClass());System.out.println(k.getClass());}
}
  • 输出结果
class java.lang.Integer
class java.lang.String

五、泛型的继承与通配符

1、基本介绍
  • 泛型不具备继承性
// 错误写法
List<Object> list1 = new ArrayList<String>();
  1. <?>:支持任意类型

  2. <? extends A>:支持 A 类以及 A 类的子类,规定了泛型的上限

  3. <? super A>:支持 A 类以及 A 类的父类,规定了泛型的下限

2、演示
  • GenericExtends.java
package com.my.test;import java.util.ArrayList;
import java.util.List;public class GenericExtends {public static void main(String[] args) {List<Object> list1 = new ArrayList<>();List<String> list2 = new ArrayList<>();List<AA> list3 = new ArrayList<>();List<BB> list4 = new ArrayList<>();List<CC> list5 = new ArrayList<>();printList1(list1);printList1(list2);printList1(list3);printList1(list4);printList1(list5);//        printList2(list1); // ×
//        printList2(list2); // ×printList2(list3);printList2(list4);printList2(list5);printList3(list1);
//        printList3(list2); // ×printList3(list3);
//        printList3(list4); // ×
//        printList3(list5); // ×}public static void printList1(List<?> list) {for (Object o : list) {System.out.println(o);}}public static void printList2(List<? extends AA> list) {for (Object o : list) {System.out.println(o);}}public static void printList3(List<? super AA> list) {for (Object o : list) {System.out.println(o);}}
}class AA {}class BB extends AA {}class CC extends BB {}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/888633.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最新,Vue 性能提升 400%

最近&#xff0c;Vue 团队核心成员 Johnson Chu 开源一个全新的信号库&#xff1a;alien-signals&#xff0c;这是一个基于 Vue 3.4 响应式系统重写的研究型信号库&#xff0c;可以使 Vue 3.4 的响应式系统性能提升 400%。目前&#xff0c;alien-signals 是所有信号库中最快的实…

springboot mvn 打包,jar和资源文件分离打包

默认打包方式如下&#xff1a; <build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><execution…

OpenHarmony-3.HDF框架(2)

OpenHarmony HDF 平台驱动 1.平台驱动概述 系统平台驱动框架是系统驱动框架的重要组成部分&#xff0c;它基于HDF驱动框架、操作系统适配层(OSAL, operating system abstraction layer)以及驱动配置管理机制&#xff0c;为各类平台设备驱动的实现提供标准模型。 系统平台驱动(…

BT1120接口自学笔记

一、技术简介 1.1名词解释 BT.1120协议是一种广泛应用的高清数字视频传输协议,能够把取样结构为4:4:4和4:4:2的视频数据编码成内嵌同步定时基准码的视频数据流进行传输。也可以用于ITU-R BT.709建议书和ITU-R BT.2100建议书规定的像素阵列为1 920*1080视屏数据传输。 经常听…

pdf转word/markdown等格式——MinerU的部署:2024最新的智能数据提取工具

一、简介 MinerU是开源、高质量的数据提取工具&#xff0c;支持多源数据、深度挖掘、自定义规则、快速提取等。含数据采集、处理、存储模块及用户界面&#xff0c;适用于学术、商业、金融、法律等多领域&#xff0c;提高数据获取效率。一站式、开源、高质量的数据提取工具&…

探索前端世界的无限可能:玩转Excel文件

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

MySQL两阶段提交目的

阶段提交的过程 事务执行阶段&#xff1a;事务开始执行&#xff0c;InnoDB执行SQL语句的具体操作&#xff0c;如数据修改、删除等&#xff0c;并将这些操作记录在内存中。写入Redo Log&#xff08;准备阶段&#xff09;&#xff1a;事务即将提交时&#xff0c;首先将事务相关的…

前端项目使用gitlab-cicd+docker实现自动化部署

GitLab CI/CD 是一个强大的工具&#xff0c;可以实现项目的自动化部署流程&#xff0c;从代码提交到部署只需几个步骤。本文将带你配置 GitLab CI/CD 完成一个前端项目的自动化部署。 前言 为什么使用cicddocker&#xff1f; 目前我们公司开发环境使用的shell脚本部署&#…

easyexcel 导出日期格式化

1.旧版本 在新的版本中formate已经被打上废弃标记。那么不推荐使用这种方式。 2.推荐方式 推荐使用另外一种方式【 Converter 】代码如下&#xff0c;例如需要格式化到毫秒【yyyy-MM-dd HH:mm:ss SSS】级别 创建一个公共Converter import com.alibaba.excel.converters.Conv…

DApp开发前端框架选择:React还是Vue?

在区块链DApp开发中&#xff0c;前端框架的选择对用户体验和开发效率至关重要。React和Vue作为两大主流前端框架&#xff0c;各自拥有广泛的开发者基础和丰富的生态支持。那么在DApp开发中&#xff0c;该如何选择适合自己的框架呢&#xff1f;下面我们来比较一下&#xff0c;看…

6. 一分钟读懂“抽象工厂模式”

6.1 模式介绍 书接上文&#xff0c;工厂方法模式只能搞定单一产品族&#xff0c;遇到需要生产多个产品族时就歇菜了。于是&#xff0c;在需求的“花式鞭策”下&#xff0c;程序员们再次绷紧脑细胞&#xff0c;创造出了更强大的抽象工厂模式&#xff0c;让工厂一次性打包多个产品…

gulp应该怎么用,前端批量自动化替换文件

背景 最近公司准备把所有项目中用到的国际化相关的key规范化&#xff0c;原因是: 一直以来公司的app和web端 在针对相同的需求以及相同的国际化语言&#xff0c;需要设置不同的两份国际化文件&#xff0c;难以维护旧版的国际化文件中&#xff0c;存在的大量值重复&#xff0c…

UML箭线图的理解和实践

在软件开发的世界里&#xff0c;UML&#xff08;统一建模语言&#xff09;作为一种标准化的建模语言&#xff0c;扮演着举足轻重的角色。UML类图更是软件开发设计和架构过程中的核心工具&#xff0c;它不仅能帮助开发者明确系统中的类及其关系&#xff0c;还能为后续的代码实现…

hive 行转列

行转列的常规做法是&#xff0c;group bysum(if())【或count(if())】 建表: CREATE TABLE table2 (year INT,month INT,amount DOUBLE );INSERT INTO table2 (year, month, amount) VALUES(1991, 2, 1.2),(1991, 3, 1.3),(1991, 4, 1.4),(1992, 1, 2.1),(1992, 2, 2.2),(1992…

【NoSQL数据库】Hbase基本操作——数据库表的增删改查

目录 一、Hbase原理 二、HBase数据库操作 三、遇到的问题和解决方法 一、Hbase原理 HBase的数据模型&#xff1a; 行键 时间戳 列族&#xff1a;contents 列族&#xff1a;anchor 列族&#xff1a;mime “com.cnn.www” T9 Achor:cnnsi.com”CNN” T8 Achor:…

【ETCD】ETCD用户密码认证

目录 概述 特殊用户和角色 root用户 root角色 用户操作 角色操作 启用身份验证 使用etcdctl进行身份验证 使用TLS通用名称 概述 etcd 2.1中增加了身份验证功能。etcd v3 API对身份验证功能的API和用户界面进行了轻微修改&#xff0c;以更好地适应新的数据模型。本指南…

王道考研编程题总结

我还在完善中&#xff0c;边复习边完善&#xff08;这个只是根据我自身总结的&#xff09; 一、 线性表 1. 结构体 #define MaxSize 40 typedef struct{ElemType data[MaxSize]&#xff1b;int length; }SqList 2. 编程题 1. 删除最小值 题意 &#xff1a;从顺序表中删除…

Vue3技术开发,使用纯CSS3动手制作一个3D环绕的相册展示效果,支持传入任意图片.3D轮播相册的组件

主要讲述封装一个3D轮播相册的组件&#xff0c;效果图如下&#xff0c;仅仅传入一个图片的数组即可&#xff0c;效果如下&#xff1a; 使用Vue3技术开发&#xff0c;支持传入任意张数的图片。 使用方法 <template><Swiper :list"list" /> </templat…

本地运行打包好的dist

首先输入打包命令 每个人设置不一样 一般人 是npm run build如果不知道可以去package.json里去看。 打包好文件如下 命令行输入 :npm i -g http-server 进入到dist目录下输入 命令cmd 输入 http-server 成功

通过华为鲲鹏认证的软件产品如何助力信创产业

软件通过华为鲲鹏认证与信创产业有着密切的联系。鲲鹏认证是华为推动信创产业发展的一项重要举措&#xff0c;通过该认证&#xff0c;软件可以在华为的生态系统中实现更好的兼容性和性能优化&#xff0c;从而推动信创产业的全面发展和国产化替代。 鲲鹏认证的定义和重要性 鲲…