Java中对泛型的理解及应用
泛型
概念:是一个未知的数据类型,是一个参数化类型
使用场景:
- 如果需要给一个类型定义属性,但是这个类型中的属性不确定,可以使用泛型来代替定义。
- 如果需要定义一个方法,但是该方法的参数列表类型和返回值类型不确定,可以使用泛型来定义。
泛型类 的定义与使用
在定义类型时,类上有泛型的使用,那么该类就是泛型类
格式:
class 类名<泛型>{ } class person<T>{private T name;}
注意事项:
如果想要在类中使用泛型,首先需要在类的声明上,声明该泛型符号
如何定义泛型:
- 泛型符号可以是任意标识符
- 但是一般使用大写的字母来表示 M T Q L
如果一个类型定义了泛型,在使用这个类型的时候,可以确定泛型也可以不确定泛型。
如果不确定泛型的话:默认使用Object来接收参数
如果确定了泛型:那么就只能使用确定的类型来接收参数
在确定泛型的时候,泛型前后要一致
后面的泛型类型可以不写,因为可以根据泛型推断,将后面的类型会默认和前面保持一致。但是<>不能省略。
可以在一个类中使用多个不同的泛型,使用几种就需要声明几种
在使用类型时,如果类型声明了多个泛型,要么一个都不指定,要么全都指定
好处:可以提高类型的扩展性
代码:
public void main(String[] args) {person p = new person();p.name = 180.2;p.age = "453";person<String, Integer> p1 = new person<>();p1.name = "chen";p1.age = 11;person<Double,Boolean> p2 = new person<>();p2.name = 18.5;p2.age = true;}class person<T,M>{T name;M age;}
泛型方法 的定义和使用
使用泛型定义的方法
格式:
修饰符 <泛型的声明> 返回值类型 方法名(){}
注意事项:
- 如果定义了一个静态方法,该静态方法中需要使用泛型,那么静态方法只能自己先声明,后使用。不能使用类上声明的泛型。
public void main(String[] args) { printValue("chen");printValue(124); //默认转换成Integer类型、只能是引用类型}//定义了一个静态方法,必须先声明泛型public static <T> void printValue(T t){System.out.println(t);}
- 如果定义了一个非静态方法,该方法既可以使用类上声明的泛型,也可以自己声明泛型。
public class E <L>{public void main(String[] args) {E e = new E();e.printValue1(11);}
//可以在类上声明
public void printValue1(L l){System.out.println(l);}
//也可以自己声明
public <L> void printValue1(L l){System.out.println(l);}
- 方法中如果需要声明泛型,也可以同时声明多个泛型
public void main(String[] args) {printValue2("chen",22);}public static <P,M> void printValue2(P t,M m){System.out.println(t);System.out.println(m);}
泛型接口 的定义和使用
概述:如果接口中的抽象方法需要使用泛型,也需要先在接口上声明该泛型
注意:
- 将来接口的实现类如果实现了接口,但是没有指定泛型类型,在实现类中默认使用Object来表示该泛型。
//接口中应用泛型
public interface A <T,M>{public T get();public void set(M m);
}
//实现类实现该接口
public class elemA implements A{@Overridepublic Object get() { //默认Object类型return null;}@Overridepublic void set(Object o) {}
}
- 实现类实现接口之后,如果需要使用该泛型,就要在实现接口时,就要指定该泛型的类型,指定的类型是谁, 就使用谁。
//接口中应用泛型
public interface A <T,M>{public T get();public void set(M m);
}
//实现类实现该接口
public class elemA implements A<String,Integer>{@Overridepublic String get() {return null;}@Overridepublic void set(Integer integer) {}
}
- 如果实现类实现接口之后,没有指定泛型,也需要使用这个泛型符号,只能在实现类中也声明该泛型。
//接口中应用泛型
public interface A <T,M>{public T get();public void set(M m);
}
//实现类实现该接口,泛型不指定,需要在类名后声明
public class elemA <T,M> implements A<T,M>{@Overridepublic T get() {return null;}@Overridepublic void set(M m) {}
}
泛型 集合对泛型的使用
概述:学习的集合是支持泛型的
可以使用泛型,也可以不使用泛型
如果定义集合之后,没有使用泛型:元素在集合中都是Object接收
如果定义集合之后,使用了泛型,元素在集合中就是定义的类型
public class Arraylist_E <T> {ArrayList<T> a = new ArrayList<>();
}
泛型定义集合的特点
- 如果定义的集合使用了泛型,那么当前集合中只能添加对应类型的元素;
- 使用集合元素特有的方法时,不需要向下转型,直接使用即可
集合遍历的总结
- 使用迭代器或者增强for循环遍历集合时,因为集合制定了确切的泛型类型,所以在使用集合的元素时不需要再向下转型
//增强for循环遍历for (String o:a){System.out.println(o); //不用向下转型}//迭代器遍历ListIterator<String> it = a.listIterator();while (it.hasNext()){String s =it.next(); //不用向下转型System.out.println(s);}
使用转数组:toArray方法遍历的时候,该方法的返回值固定是Object类型
所以使用元素的特殊方法时,也需要向下转型。
但是转数组,有另外一种方式:toArray(T[] arr)
在转数组的时候,可以自主准备一个数组,用来存储元素,数组可以和数据的类 型保持一致,那么在转换之后也不需要向下转型。
- 如果准备的数组空间正好够存,或者空间多余元素,那么可以转移到自己的数组中。
- 如果准备的数组空间不够存储元素,该方法会返回一个新数组用来存储数据。
//转数组遍历String[] strs = new String[a.size()];for (int i = 0; i < strs.length; i++) {String s = strs[i];System.out.println(s);}
泛型 的通配符
概述:将来定义数据类型时,如果这个数据类型不确定,可以使用泛型来表示这个不确 定的类型;也可以使用泛型通配符来定义这个不确定的类型。
分类:
- ?:泛型的通配符 可以表示任何泛型
public static void main(String[] args) {ArrayList<Object> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();ArrayList<Number> list3 = new ArrayList<>();ArrayList<String> list4 = new ArrayList<>();getList1(list1);getList1(list2);getList1(list3);getList1(list4); public static void getList1(ArrayList<?> list){}
//都可以
- ? extends E: 泛型通配符 可以表示泛型E类型或者泛型E类型子类类型
public static void main(String[] args) {ArrayList<Object> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();ArrayList<Number> list3 = new ArrayList<>();ArrayList<String> list4 = new ArrayList<>();getList2(list1); //Object 不行getList2(list2); //Integer 可以getList2(list3); //Number 可以getList2(list4); //String 不行//? extends Number:表示可以接收Number类型或者Number子类类型public static void getList2(ArrayList<? extends Number> list){}
- ? super E: 泛型通配符 可以表示泛型E类型或者泛型E类型的父类类型
public static void main(String[] args) {ArrayList<Object> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();ArrayList<Number> list3 = new ArrayList<>();ArrayList<String> list4 = new ArrayList<>();getList3(list1); //Object 可以getList3(list2); //Integer 不行getList3(list3); //Number 可以getList3(list4); //String 不行//? super Number:表示可以接收Number类型或者Number父类类型public static void getList3(ArrayList<? super Number> list){}
Java中对泛型的理解及应用相关推荐
- Java中的泛型 --- Java 编程思想
前言 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...
- java定义list_我的Java Web之路59 - Java中的泛型
本系列文章旨在记录和总结自己在Java Web开发之路上的知识点.经验.问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人. 目录 介绍 再谈Java中的类型 为什么需要泛型? J ...
- [转载] 详解Java中的泛型
参考链接: Java中具有泛型的有界类型 1.什么是泛型 泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名 ...
- java如何用反射把具体方法抽象_如何在Java 中使用泛型或反射机制对DAO进行抽象...
如何在Java 中使用泛型或反射机制对DAO进行抽象 发布时间:2020-11-26 16:07:42 来源:亿速云 阅读:80 作者:Leah 本篇文章为大家展示了如何在Java 中使用泛型或反射机 ...
- Java中的泛型全解析(一)
为什么我们需要泛型? 通过两段代码我们就可以知道为何我们需要泛型 实际开发中,经常有数值类型求和的需求,例如实现int类型的加法, 有时候还需要实现long类型的求和, 如果还需要double类型的求 ...
- Java中Map集合如何理解(四)——精简
目录 引言 概念 Map集合实现类 HashMap LinkedHashMap TreeMap 默认排序 自定义排序方式 常用API 遍历Map集合 键找值 键值对 Lambda表达式 结束语 引言 ...
- Java 中的泛型(两万字超全详解)
文章目录 前言 一.泛型概述 1. 什么是泛型?为什么要使用泛型? 2. 泛型使用场景 3. 泛型概述小结 二.泛型类 1. 泛型类的定义 2. 泛型类的使用 三.泛型接口 四.泛型方法 1. 泛型方 ...
- Java中创建泛型数组
Java中创建泛型数组 使用泛型时,我想很多人肯定尝试过如下的代码,去创建一个泛型数组 T[] array = new T[]; 当我们写出这样的代码时编译器会报Cannot create a gen ...
- 【笔记】JAVA中的泛型和反射
泛型 Java的泛型是如何工作的?什么是类型擦除? ----泛型是通过类型擦除来实现的,编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息.例如List在运行时仅用一个Lis ...
最新文章
- ajax中的url如何传递变量_如何创建和参数化UDT数据类型中的变量及IN,OUT 等参数?...
- 重启redis命令_redis系列之——数据持久化(RDB和AOF)
- 卸载注册表_系统小技巧:软件卸载不了?这里办法多
- No fallback instance of type class found for feign client user-service(转)
- python中的异或操作_Python中的异或和位操作的反转
- mysql having的用法
- 去除eclipse打开后不断update的问题
- mysql ibd文件还原_MySQL
- c语言寻找文件指令,c语言实现文件查找
- 基于Android幼儿园管理系统,幼儿园管理系统
- 01.J2EE开发环境搭建
- 2021最新阿里代码规范(前端篇)
- 一文带你看透手机号码归属地
- Adobe Photoshop CC2014 安装过程
- Win7/10/11:去除、恢复软件图标小箭头
- 电脑远程桌面连接怎么操作?
- contents()与children()的用法和区别
- 0.96寸OLED屏使用详解
- Python课程设计项目-基于机器学习的糖尿病风险预警分析系统
- 腾讯php开发工程师面试题
热门文章
- 哺乳期哪些事不能做?
- com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:Unrecognized field
- MySQL tips
- 天龙八部天外服务器不响应,有生命的服务器 天龙八部3智能天外江湖
- JS输入3个数,判断是否构成三角形,如构成,是直角还是锐角钝角三角形呢
- 2020.2.22GDUT寒假训练排位赛2-H
- Vue超详细(已完结)
- Android 导入v7包常见错误,以及项目引用v7包错误解决,
- 浙工大服务器实现优雅地上网
- 关键词采集网址软件【速度极快】