泛型(generics)

目录

一、泛型概述

二、定义泛型类

三、定义泛型方法

四、List接口中的泛型是如何定义的

五、泛型通配符

六、 泛型通配符的上限和下限

七、可变参数

八、可变参数的使用

九、泛型擦除机制


一、泛型概述

  1. Java泛型是JDK5中引入的一个新特性,提供了编译时类型安全检查机制-----编译时检测到非法的类型。

  2. 早期的时候,使用Object来代表任意类型。这样在向上转型的是没有问题,但是在向下转型时存在类型转换的问题,这样程序不安全。Java在IDK5之后提供泛型来解决这个问题。

  3. 泛型的本质是参数化类型,也就是说操作的数据类型被指定为一个参数,

  4. 泛型是一种,把类型的明确工作推迟到创建对象或者调用方法的时候才去明确的特殊类型。

    注意:类型参数只能代表引用型类型不能是原始类型(像int,double,char的等)。

    泛型可以使用在 方法、接口、类中------------泛型类、泛型方法、泛型接口。

二、定义泛型类

  • 格式:修饰符 class 类名<类型>{}

  • 范例:public class Mayikt<T>{}

  • 此处T可以随便写为任意标识,T、E、K、V等形式的参数常用于表示泛型。

package com.dev.springBootDemo.generics;
​
/*** 泛型类* @author zhumq* @date 2024/7/7 12:54*/
public class Student<T> {
​private T t;
​public T getT() {return t;}
​public void setT(T t) {this.t = t;}
​
}

package com.dev.springBootDemo.generics;
​
/*** 测试泛型* @author zhumq* @date 2024/7/7 12:56*/
public class TestGenerics {public static void main(String[] args) {Student<String> student = new Student<>();student.setT("zhumq");System.out.println(student.getT()); // zhumq
​Student<Integer> student1 = new Student<>();student1.setT(1);System.out.println(student1.getT()); // 1
​Student<Double> student2 = new Student<>();student2.setT(1.0);System.out.println(student2.getT()); // 1.0
​Student student3 = new Student<>(); // 没有指定类型,默认为Object,注意类型转化}
}

三、定义泛型方法

  • 格式:修饰符<类型>返回值类型 方法名(类型 变量名){..}

  • 范例:public<T>T show(T t){...}

package com.dev.springBootDemo.generics2;
​
/*** 泛型方法* @author zhumq* @date 2024/7/7 13:02*/
public class Method {/*** <T> 该方法使用泛型* T 返回值*/public <T> T show(T t) {return t;}
}
​

package com.dev.springBootDemo.generics2;
​
/*** @author zhumq* @date 2024/7/7 13:10*/
public class TestGenerics {public static void main(String[] args) {Method m = new Method();System.out.println(m.show("zhumq")); // zhumqSystem.out.println(m.show(1)); // 1System.out.println(m.show(1.1)); // 1.1}
}
​

四、定义泛型接口

  • 格式:修饰符interface 接口名<类型>{..}

  • 范例:public interface Mayiktlnterface <T>....}

  • 实现类也要有<T>

package com.dev.springBootDemo.generics3;
​
/*** @author zhumq* @date 2024/7/7 13:15*/
public interface Interface<T> {T show(T t);
}
​

package com.dev.springBootDemo.generics3;
​
/*** @author zhumq* @date 2024/7/7 13:16*/
public class InterfaceImpl<T> implements Interface<T> {@Overridepublic T show(T t) {return t;}
}
​

package com.dev.springBootDemo.generics3;
​
/*** @author zhumq* @date 2024/7/7 13:14*/
public class TestGenerics {public static void main(String[] args) {Interface<String> i = new InterfaceImpl<>();System.out.println(i.show("hello")); // helloInterface<Integer> i2 = new InterfaceImpl<>();System.out.println(i2.show(1)); // 1}
}
​

四、List接口中的泛型是如何定义的

package com.dev.springBootDemo.generics4;
​
/*** List中的泛型* @author zhumq* @date 2024/7/7 13:25*/
public interface MyList<E> {void  add(E e);E get(int index);
}
​
package com.dev.springBootDemo.generics4;
​
/*** @author zhumq* @date 2024/7/7 13:26*/
public class MyListImpl<E> implements MyList<E> {@Overridepublic void add(E e) {System.out.println("新增成功!!!");}
​@Overridepublic E get(int index) {System.out.println("获取成功!!!");E e = null;return e;}
}
​
package com.dev.springBootDemo.generics4;
​
/*** @author zhumq* @date 2024/7/7 13:28*/
public class TestGenerics {public static void main(String[] args) {MyList<String> myList = new MyListImpl<>();myList.add("hello");}
}
​

五、泛型通配符

  1. 类型通配符<?>一般用于接受使用

  2. List<?>:表示元素是未知类型的list,可匹配任何类型

  3. 带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中

  4. 类型通配符上限:<?extends 类型> List<? extends MaviktParent>:它表示的类型是MaviktParent或其子类型

  5. 类型通配符下限:<? super 类型> List<? super MayiktParent>:它表示的类型是MayiktParent或其父类型

package com.dev.springBootDemo.generics5;
​
import javax.xml.transform.sax.SAXTransformerFactory;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
​
/*** 通泛型配符* @author zhumq* @date 2024/7/7 13:32*/
public class TestGenerics {public static void main(String[] args) {ArrayList<String> stringList = new ArrayList<>();for (int i = 0 ; i < 5 ; i++) {stringList.add("i:" + i);}printList(stringList);
//        ArrayList<Integer> integerList = new ArrayList<>();
//        printList(integerList);}
​// 不能add操作,可以get,获取类型为Objectpublic static void printList (List<?> list) {Iterator<?> iterator = list.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}
​

六、 泛型通配符的上限和下限

package com.dev.springBootDemo.generics6;
​
import java.util.ArrayList;
import java.util.List;
​
/*** @author zhumq* @date 2024/7/7 13:46*/
public class TestGenerics {public static void main(String[] args) {ArrayList<Parent> parents = new ArrayList<>();ArrayList<Chlidren> children = new ArrayList<>();printList(parents);printList(children);ArrayList<Object> objects = new ArrayList<>();printList2(objects);}
​/*** 类型通配符上限* List<? extends Parent>  上限, 表示list中存放的元素类型是Parent或者Parent的子类** @param list*/public static void printList(List<? extends Parent> list){}
​/*** 类型通配符下限* List<? super Parent>  下限, 表示list中存放的元素类型是Parent或者Parent的父类** @param list*/public static void printList2(List<? super Parent> list){}
​
}
​
​

七、可变参数

  • 可变参数:又称参数个数可变,用作方法的形参出现,那么方法参数个数就是 可变的了。

  • 书写格式

    1. 修饰符 返回值类型 方法名(数据类型...量名){)

    2. 范例:public static int sum(int... a){}

  • 可变参数注意事项

    • 这里的可变参数变量其实是一个数组。

    • 如果一个方法有多个参数,包含可变参数,可变参数要放在最后

package com.dev.springBootDemo.generics7;
​
/*** @author zhumq* @date 2024/7/7 14:05*/
public class TestGenerics {public static void main(String[] args) {System.out.println(sum(1, 2, 3, 4, 5));}
​/*** 可变参数 ,底层是数组* 传递的参数列表是一个数组*/public static int sum (int b,int ...a) {// a做累加处理,减去b  2-5累加 减去1int sum = 0;for (int i = 0; i < a.length; i++) {sum += a[i];}sum -= b;return sum;}
}

八、可变参数的使用

package com.dev.springBootDemo.generics8;
​
import java.util.Arrays;
import java.util.List;
​
/*** @author zhumq* @date 2024/7/7 14:14*/
public class TestGenerics {public static void main(String[] args) {// 定义的元素个数是不能改变的,可以修改数据List<String> list = Arrays.asList("张三", "李四", "王五");// list.remove(0);// 不能删除// list.add("赵六");// 不能添加list.set(0, "赵六");System.out.println(list);}
}

九、泛型擦除机制

  • 泛型底层底层原理,使用擦除机制

  • 泛型在编译阶段限制传递的类型,意味着在编译阶段,所有泛型类型信息都会被从字节码中移除(擦除),只留下原始类型

  • 在运行的时候是没有泛型的,可以对.class文件进行反编译进行观察

package com.dev.springBootDemo.generics9;
​
import java.util.ArrayList;
import java.util.List;
​
/*** @author zhumq* @date 2024/7/7 14:22*/
public class TestGenerics {// public static void main(String[] args) {//     ArrayList<String> strings = new ArrayList<>();//     strings.add("张三");//     // 泛型擦除:将一个指定的泛型类型赋值给一个没有指定泛型类型的变量,就会发生泛型擦除//     ArrayList arrayList = strings;//     arrayList.add(1);// }
​public static void main(String[] args) {// 创建一个泛型列表,只允许存放 String 类型List<String> stringList = new ArrayList<>();stringList.add("Hello");stringList.add("World");Class<? extends List> aClass = stringList.getClass();// 创建一个泛型列表,只允许存放 Integer 类型List<Integer> integerList = new ArrayList<>();integerList.add(1);integerList.add(2);Class<? extends List> aClass1 = integerList.getClass();
​// 检查两个列表的类型是否相同System.out.println(stringList.getClass() == integerList.getClass()); //true}
}
/*这表明尽管我们在编译时指定了不同的泛型参数(String 和 Integer),但在运行时,stringList 和 integerList 都被识别为 java.util.ArrayList 类的实例,而不是 ArrayList<String> 或 ArrayList<Integer>。
这是因为编译器在编译阶段会执行类型擦除,将所有的泛型类型转换为它们的原始类型。在这个例子中,List<String> 和 List<Integer> 都被转换为 List,并且 ArrayList<String> 和 ArrayList<Integer> 都被转换为 ArrayList。*/

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

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

相关文章

Adobe Premiere Pro 2024 v24.5 (macOS, Windows) - 专业视频编辑软件

Adobe Premiere Pro 2024 v24.5 (macOS, Windows) - 专业视频编辑软件 Acrobat、After Effects、Animate、Audition、Bridge、Character Animator、Dimension、Dreamweaver、Illustrator、InCopy、InDesign、Lightroom Classic、Media Encoder、Photoshop、Premiere Pro、Adob…

在Ubuntu 16.04上安装和配置Redis的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 Redis 是一个内存中的键值存储&#xff0c;以其灵活性、性能和广泛的语言支持而闻名。在本指南中&#xff0c;我们将演示如何在 U…

【Selenium配置】WebDriver安装浏览器驱动(ChromeEdge)

【Selenium配置】WebDriver安装浏览器驱动&#xff08;Chrome&Edge&#xff09; 文章目录 【Selenium配置】WebDriver安装浏览器驱动&#xff08;Chrome&Edge&#xff09;Chrome确认Chrome版本下载对应driver把解压后的chromedriver文件放在chrome安装目录下&#xff0…

算法简介:什么是算法?——定义、历史与应用详解

引言 在现代计算机科学中&#xff0c;算法是一个核心概念。无论是编程还是数据分析&#xff0c;算法都扮演着至关重要的角色。在这篇博客中&#xff0c;我们将深入探讨算法的定义、历史背景以及它在计算机科学中的地位和实际应用。 什么是算法&#xff1f; 算法是解决特定问题…

Linux 定期自动修改密码,防止过期

背景 😂 Jenkins 中使用 ssh 密码登录,实现项目前端部署。 😂 ssh 账号(假设叫做 ft)每隔三个月就会过期,就会导致前端部署报错,提示“Your password is expired” 😂 每次修改密码,需要申请权限,审批,耗时较长。=》希望自动修改密码,防止过期 分析 1、模拟生…

表格布局的概念与属性

表格布局的概念与属性 表格布局&#xff08;TableLayout&#xff09;是以行、列的形式来管理控件的&#xff0c;类似与表格。如图所示&#xff0c;是一个表格布局。TableLayout继承自LinearLayout&#xff0c;支持LinearLayout所支持的全部属性&#xff0c;默认为垂直方向的Li…

在线制作网页PHP源码+IAPPv3源码

好久以前刚学PHP的时候搞的&#xff0c;现在翻出来并修复了一下就分享出来了&#xff0c;希望可以给初学者一点借鉴学习例子&#xff0c;虽然不是很好哈&#xff0c;但拿来耍耍应该还算可以吧。 使用教程 环境是PHP就行&#xff0c;直接把源码上传到服务器&#xff08;虚拟主…

React-Native中关于图片问题知识总结

系列文章目录 React-Native环境搭建&#xff08;IOS&#xff09;React-Native项目 — 关于IOS知识储备React-Native项目工程搭建&#xff08;开发模板搭建&#xff09;React-Native项目矢量图标库&#xff08;react-native-vector-icons&#xff09;React-Native项目 — 自定义…

Transformer-LSTM预测 | Matlab实现Transformer-LSTM多变量时间序列预测

Transformer-LSTM预测 | Matlab实现Transformer-LSTM多变量时间序列预测 目录 Transformer-LSTM预测 | Matlab实现Transformer-LSTM多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现Transformer-LSTM多变量时间序列预测&#xff0c;Transf…

JavaWeb开发基础7个Web术语解析

7个Web术语 Website: static vs dynamic HTTP HTTP Requests GET vs POST Servlet Container Server: Web vs Application Content Type Website: static vs dynamic 网站内容包括文本、图片、音频、视频&#xff0c;通过URL来访问。网站分为静态网站和动态网站。 静态网…

【计算机组成原理实验】——实验 MIPS 指令系统和 MIPS 体系结构

实验 MIPS 指令系统和 MIPS 体系结构 一、实验目的 了解和熟悉指令级模拟器。 熟练掌握 MIPSsim 模拟器的操作和使用方法。 熟悉 MIPS 指令系统及其特点&#xff0c;加深对 MIPS 指令操作语义的理解。 熟悉 MIPS 体系结构。 二、实验平台 实验平台采用指令级和流水线操作…

通用的职位招聘小程序ui模板

蓝色简单的校园招聘&#xff0c;行业招聘&#xff0c;职位招聘手机小程序页面模板。包含&#xff1a;职位列表、职位详情、基本信息填写、登录、个人主页、消息页面等功能 通用的职位招聘小程序ui模板

洛谷 P3613 学习用map代替大大大数组的好题

题目链接&#xff1a;P3613 【深基15.例2】寄包柜 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目截图&#xff1a; 题意分析&#xff1a; 非常简单的存入和取出操作 唯一的 “难点” 在于 数组开不到 a[100007][100007]&#xff0c;会暴内存 非常巧妙的引入 map 来解决…

Springboot 3.x - Reactive programming

一、Preliminary Knowledge Functional InterfaceLambda expressionStream API Intermediate operation filter&#xff1a;Used to filter elements in a streammap&#xff1a;One-to-one conversionflatMap&#xff1a;One-to-many conversiondistinct、sorted、peek、limi…

详解Java垃圾回收(GC)机制

一、为什么需要垃圾回收 如果不进行垃圾回收&#xff0c;内存迟早都会被消耗空&#xff0c;因为我们在不断的分配内存空间而不进行回收。除非内存无限大&#xff0c;我们可以任性的分配而不回收&#xff0c;但是事实并非如此。所以&#xff0c;垃圾回收是必须的。 二、哪些内…

【ARMv8/v9 GIC 系列 1.8 -- PE 中断处理的前期评估】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 Interaction of group and individual interrupt enablesLPIs的启用Interaction of group and individual interrupt enables 在ARM GICv3和GICv4架构中,GICD_*和GICR_*寄存器组 决定了处理器元素(PE)能够识别的最高优先级 pend…

【Java】了解异常

初始异常 我们平时应该已经接触过一些 “异常” 了&#xff0c;这里列举一些例子。 算术异常&#xff1a; 数组下标越界异常&#xff1a; 访问空指针异常&#xff1a; 所谓异常指的就是程序在 运行时 出现错误时通知调用者的一种机制。 异常的基本用法 捕获异常 try{ 有可能…

使用静态图加速

背景介绍 AI编译框架分为两种运行模式&#xff0c;分别是动态图模式以及静态图模式。MindSpore默认情况下是以动态图模式运行&#xff0c;但也支持手工切换为静态图模式。两种运行模式的详细介绍如下&#xff1a; 动态图模式 动态图的特点是计算图的构建和计算同时发生&…

Open3D 删除点云中重叠的点(方法一)

目录 一、概述 二、代码实现 三、实现效果 3.1原始点云 3.2处理后的点云 3.3计算结果 一、概述 在点云处理中&#xff0c;重叠点&#xff08;即重复点&#xff09;可能会对数据分析和处理的结果产生负面影响。因此&#xff0c;删除重叠点是点云预处理中常见且重要的步骤。…

C++标准库常用的遍历和查找算法

文章目录 1.常用遍历算法1.for_each2.transform 2.常用查找算法1. find2. find_if3. adjacent_find4. binary_search5. count6. count_if 1.常用遍历算法 1.for_each C的std::for_each算法是标准库中的一个迭代器算法&#xff0c;它对容器或范围内的每个元素执行指定的操作。…