泛型复习(java)

文章目录

  • 泛型
    • 为什么用泛型
    • 泛型特性
    • 泛型的擦出和补偿
    • 自定义泛型
      • 在类上自定义泛型
      • 在方法上使用泛型
      • 在接口上定义泛型
    • 类型通配符

泛型

为什么用泛型

不用泛型

public class User {public static void main(String[] args) {//创建 arraylist 集合Collection arraylist = new ArrayList();//把 Person 对象假如 arraylistPerson p = new Person();arraylist.add(p);//用迭代器遍历调用 test 方法Iterator it =  arraylist.iterator();while (it.hasNext()) {Object o = it.next();//这里非常麻烦,要向下转型,所以我们可以用泛型if (o instanceof Person) {Person temp = (Person) o;temp.test();}}}
}class Person {public void test() {System.out.println("调用 test 方法");}
}

使用泛型

public class User {public static void main(String[] args) {//创建 arraylist 集合Collection<Person> arraylist = new ArrayList<>();//把 Person 对象假如 arraylistPerson p = new Person();arraylist.add(p);//用迭代器遍历调用 test 方法Iterator<Person> it =  arraylist.iterator();while (it.hasNext()) {//这里用了泛型所以代码更简便了,也不用向下转型了,并且编译会进行类型检查,更安全了Person temp = it.next();temp.test();}}
}class Person {public void test() {System.out.println("调用 test 方法");}
}



泛型特性

  1. 泛型是 java5 的新特性,属于编译阶段的功能
  2. 让开发者指定集合中存储的数据类型
//这里就表示只能存 String 类型数据,否则编译阶段报错
Arraylist<String> al = new ArrayList<String>();

作用

  1. 类型安全:指定集合中元素类型后,编译器会进行类型检查,如果尝试将类型错误的元素添加到集合中,就会在编译时报错,避免了运行时出现的错误问题
  2. 代码简洁:避免频繁类型转换,因为不用泛型集合就默认返回Object

钻石表达式

java7 的新特性

//后面<>里的 String 可以省略
Arraylist<string> a1 = new ArrayList();



泛型的擦出和补偿

擦除

  • 泛型提高安全性,是编译阶段的技术,专门给编译器用的,加载类的时候,会把泛型擦除掉,擦成 Object 类型
  • 擦除的本质是让 JDK1.4之前的 和 JDK1.5 能兼容同一个类加载器,1.5擦除后为 Object 和 1.4 之前就兼容了

补偿

  • 擦除为 Object 类型,所以添加的元素就被转化为 Object 类型,同时取出的元素也默认为 Object 类型
  • 这里有一个默认的操作:他帮你自动把 Object 强转成对应的类型,不用强转



自定义泛型

在类上自定义泛型

public class User {public static void main(String[] args) {//下面Person类所有 T 都替换为 StringPerson<String> p = new Person<>("张三");}
}//如果多个泛型就用 逗号 隔开
class Person<T1> {private T name;public Person(T name){this.name = name}public T getName() {return name;}public void setName(T name) {this.name = name;}
}

这个 T 是自定义的 名字可以随意取



在方法上使用泛型

class Person<R> {    //这个 T  和 T 对应属于泛型方法,R 和 r 对应属于泛型类public <T> void method(T t, R r) 
}

在类上定义的泛型,静态方法中无法使用,如果在静态方法中使用泛型则需要在返回值类型前进行泛型声明

class Person<T1> {public staic void setName(T name) {this.name = name;}
}

因为如果静态方法能使用,你用类名.方法 (Person.setName),直接调用,定义不了泛型直接寄了

如果要在静态上用泛型,就要使用自定义泛型方法

class Person {//提前定义好 T1//这个 T 是属于这个方法的泛型public staic <T> void setName(T name) {this.name = name;}
}



在接口上定义泛型

接口继承时定义泛型

interface IA extends IUsb<String, Double> {}
//当我们去实现IA接口时,因为IA在继承IUsu 接口时,指定了U 为String R为Double
//,在实现IUsu接口的方法时,使用String替换U, 是Double替换R
class AA implements IA {@Overridepublic Double get(String s) {return null;}@Overridepublic void hi(Double aDouble) {}@Overridepublic void run(Double r1, Double r2, String u1, String u2) {}
}interface IUsb<U, R> {int n = 10;//U name; 不能这样使用//普通方法中,可以使用接口泛型R get(U u);void hi(R r);void run(R r1, R r2, U u1, U u2);//在jdk8 中,可以在接口中,使用默认方法, 也是可以使用泛型default R method(U u) {return null;}
}

实现接口时定义泛型

//实现接口时,直接指定泛型接口的类型
//给U 指定Integer 给 R 指定了 Float
//所以,当我们实现IUsb方法时,会使用Integer替换U, 使用Float替换R
class BB implements IUsb<Integer, Float> {@Overridepublic Float get(Integer integer) {return null;}@Overridepublic void hi(Float aFloat) {}@Overridepublic void run(Float r1, Float r2, Integer u1, Integer u2) {}
}interface IUsb<U, R> {int n = 10;//U name; 不能这样使用//普通方法中,可以使用接口泛型R get(U u);void hi(R r);void run(R r1, R r2, U u1, U u2);//在jdk8 中,可以在接口中,使用默认方法, 也是可以使用泛型default R method(U u) {return null;}
}

没有指定接口

//没有指定类型,默认为Object
//建议直接写成 IUsb<Object,Object>
class CC implements IUsb { //等价 class CC implements IUsb<Object,Object> {@Overridepublic Object get(Object o) {return null;}@Overridepublic void hi(Object o) {}@Overridepublic void run(Object r1, Object r2, Object u1, Object u2) {}}interface IUsb<U, R> {int n = 10;//U name; 不能这样使用//普通方法中,可以使用接口泛型R get(U u);void hi(R r);void run(R r1, R r2, U u1, U u2);//在jdk8 中,可以在接口中,使用默认方法, 也是可以使用泛型default R method(U u) {return null;}
}

简单来说就是在 继承接口,或实现接口时指定泛型

接口中,静态成员也不能使用泛型 (接口中)




类型通配符

泛型不具备继承性

也就是 如果你是 Number 那就是 Number 不能是它的 子类

比如集合定义好了泛型,你不确定存声明类型,直接 ArrayList<?>

  • 无限定通配符:<?>:可以为任意引用数据类型
  • 上限通配符:<? extends Numbers>:必须为 Numbers 或者它的子类
  • 下限通配符:<? super Numbers>:必须为 Numbers 或者它的父类
public class User {public static void main(String[] args) {//啥类型都可以User.test(new ArrayList<String>());User.test(new ArrayList<Double>());//只能是 Number 和 Number 的子类User.test2(new ArrayList<Double>());//只能是 Double 和 Double 的父类User.test3(new ArrayList<Number>());}public static void test(ArrayList<?> list){}public static void test2(ArrayList<? extends Number> list){}public static void test3(ArrayList<? super Double> list){}
}

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

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

相关文章

利用Cesium和JS实现地点点聚合功能

引言 在实现基于地图的业务场景时&#xff0c;当地图上需要展示过多的标记点时&#xff0c;大量的分散点会使地图上显得杂乱无章&#xff0c;导致标记点对地图上的其他重要信息造成遮挡和混淆&#xff0c;降低地图整体的可读性。 标记点的聚合就很好的解决了这些痛点的同时&a…

[大模型]XVERSE-MoE-A4.2B Transformers 部署调用

XVERSE-MoE-A4.2B介绍 XVERSE-MoE-A4.2B 是由深圳元象科技自主研发的支持多语言的大语言模型&#xff08;Large Language Model&#xff09;&#xff0c;使用混合专家模型&#xff08;MoE&#xff0c;Mixture-of-experts&#xff09;架构&#xff0c;模型的总参数规模为 258 亿…

apt-get update和apt-get upgrade的区别

apt-get update apt-get update 命令用于更新本地软件包列表。具体来说&#xff0c;做了以下事情&#xff1a; ①从 /etc/apt/sources.list 文件和 /etc/apt/sources.list.d/ 目录下的所有文件中读取软件源配置。 ②连接到这些软件源&#xff0c;并下载最新的软件包列表。 ③将…

springcloud入门与实践

Spring Cloud 是一个基于 Spring Boot 的框架&#xff0c;专注于微服务架构下的常见问题&#xff0c;如服务发现、负载均衡、断路器、分布式配置、消息驱动的微服务等。以下是 Spring Cloud 的入门指南和实践示例。 1. 环境准备 首先&#xff0c;确保你已经安装了以下工具&am…

Python 潮流周刊#56:NumPy 2.0 里更快速的字符串函数

△△请给“Python猫”加星标 &#xff0c;以免错过文章推送 本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景&#xff1a;帮助所有读者精进 Python 技术&am…

Mysql(一):深入理解Mysql索引底层数据结构与算法

众所众知&#xff0c;MySql的查询效率以及查询方式&#xff0c;基本上和索引息息相关&#xff0c;所以&#xff0c;我们一定要对MySql的索引有一个具体到数据底层上的认知。 这一次也是借着整理的机会&#xff0c;和大家一起重新复习一下MySql的索引底层。 本节也主要有一下的…

AOSP : Android编译记录

Android编译记录 1、关注编译配置文件2、编译记录2.1 设置构建环境2.2 记录 1、关注编译配置文件 Android.bp 或 Android.mk Android.bp 文件格式 2、编译记录 2.1 设置构建环境 source build/envsetup.sh lunch product_name-release-build_variant查看当前的启动设置&#…

【PL理论】(25) C- 语言:表达式求值的推理规则 | 执行语句的推理规则 | 语句执行的推理规则

&#x1f4ad; 写在前面&#xff1a;本章我们将继续更新我们的 "C-" 语言&#xff0c;更新表达式求值的推理规则、执行语句的推理规则以及语句执行的推理规则。 目录 0x00 C- 语言更新&#xff1a;表达式求值的推理规则 0x01 C- 语言更新&#xff1a;执行语句的推…

网页五子棋对战项目测试(selenium+Junit5)

目录 网页五子棋对战项目介绍 网页五子棋对战测试的思维导图​ 网页五子棋对战的UI自动化测试 测试一&#xff1a;测试注册界面 测试二&#xff1a;测试登陆界面 测试三&#xff1a;测试游戏大厅界面 测试四&#xff1a;测试游戏房间界面以及观战房间界面 测试五&#…

【技巧】Leetcode 67. 二进制求和【简单】

二进制求和 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。 示例 1&#xff1a; 输入:a “11”, b “1” 输出&#xff1a;“100” 示例 2&#xff1a; 输入&#xff1a;a “1010”, b “1011” 输出&#xff1a;“10101” 解题思路 …

软考-架构设计师-综合知识总结(试卷:2009~2022)(下篇)

说明 本文档对2009到2022年试卷的综合知识进行了归纳总结&#xff0c;同时对叶宏主编的《系统架构设计师教程》划分重点。 第十七章&#xff1a;通信系统架构设计 17.2 考题总结 第十八章&#xff1a;安全架构设计 18.1 重要知识点 18.2 考题总结 第十九章&#xff1a;大数据…

传统后端SQL数据层替代解决方案: 内置数据源+JdbcTemplate+H2数据库 详解

内置数据源 我们回顾一下druid数据源的配置方式 通过type属性指定数据源的类型 导入依赖 starter就使用了spring的自动装配功能 格式二是在引入druid的依赖的基础上 进行的一种配置方式 Tomcat内部也可以进行数据源的配置 轻量级中最快的数据源对象 我们切换德鲁伊连接池 我…

OpenDevin 环境配置及踩坑指南

不惧怕任何环境配置 首先 clone 项目&#xff0c;然后查看开发者文档&#xff1a;https://github.com/OpenDevin/OpenDevin/blob/main/Development.md make setup-config 自定义 LLM 配置 首先这个 devin 写的是支持自定义的 LLM 配置&#xff0c;并且提供了交互式命令供我们…

DzzOffice集成功能最丰富的开源PHP+MySQL办公系统套件

DzzOffice是一套开源办公套件&#xff0c;旨在为企业和团队提供类似“Google企业应用套件”和“微软Office365”的协同办公平台。以下是对DzzOffice的详细介绍&#xff1a; 主要功能和应用&#xff1a; 网盘&#xff1a;支持企业、团队文件的集中管理&#xff0c;提供文件标签…

app-ios 内嵌h5的缓存问题

在iOS应用中内嵌H5页面时&#xff0c;可能会遇到缓存问题&#xff0c;导致页面更新不及时。以下是一些解决策略和方法&#xff1a; 目录 方法1&#xff1a;Nginx配置 方法2&#xff1a;使用版本号 方法1&#xff1a;Nginx配置 通过Nginx服务器配置来控制缓存行为。例如&#…

Python开发示例——使用Python实现炫酷的数据动态图

前言 数据可视化是通过图形、图表、地图等可视元素将数据呈现出来&#xff0c;以便更容易理解、分析和解释。它是将抽象的数据转化为直观形象的过程&#xff0c;有助于发现数据中的模式、趋势和关系。数据可视化对于数据科学、商业分析、决策制定等领域都至关重要。当我们想用…

UniApp+Vue3使用Vant-微信小程序组件

第一步&#xff1a;打开创建好的UniappVue3的项目 第二步&#xff1a;下载Vant-Weapp npm i vant/weapp -S --production 第三步&#xff1a;修改目录名称 wxcomponents 必须是wxcomponents 第四步&#xff1a;将下载好的vant中的dist目录剪切到当前wxcomponents目录下 第五…

在 Linux 上刷新 DNS 缓存:告别过时解析,提升网络访问效率

引言 在 Linux 系统中&#xff0c;DNS&#xff08;域名系统&#xff09;缓存对于提高网络访问速度和效率至关重要。然而&#xff0c;当 DNS 记录发生更改或需要更新时&#xff0c;旧的缓存条目可能会导致访问问题或连接到错误的服务器。因此&#xff0c;了解如何在 Linux 上刷…

leetcode打卡#day51 300. 最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

300. 最长递增子序列 class Solution { public:int lengthOfLIS(vector<int>& nums) {if (nums.size() < 1) return nums.size();vector<int> dp(nums.size(), 1);int result 0;for (int i 1; i < nums.size(); i) {for (int j 0; j < i; j) {if …

牛客网金九银十最新版互联网Java高级工程师面试八股文出炉!面面俱到,太全了

前言 作为一个 Java 程序员&#xff0c;你平时总是陷在业务开发里&#xff0c;每天噼里啪啦忙敲着代码&#xff0c;上到系统开发&#xff0c;下到 Bug 修改&#xff0c;你感觉自己无所不能。然而偶尔的一次聚会&#xff0c;你听说和自己一起出道的同学早已经年薪 50 万&#x…