Java中的泛型讲解【最详细】【精美版】
可以看下我亲自录制的视频讲解:
【布道者】Ep_集合-泛型_哔哩哔哩_bilibili
点我进入
问题
在前面学习集合时,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。
看如下的代码:
public class GenericDemo {public static void main(String[] args) {Collection coll = new ArrayList();coll.add("无鸡");coll.add("无忌");coll.add(5);//由于集合没有做任何限定,任何类型都可以给其中存放Iterator it = coll.iterator();while(it.hasNext()){//需要打印每个字符串的长度,就要把迭代出来的对象转成String类型String str = (String) it.next();System.out.println(str.length());}}
}
程序在运行时发生了问题java.lang.ClassCastException。
为什么会发生类型转换异常呢?
分析下:由于集合中什么类型的元素都可以存储。导致取出时强转引发运行ClassCastException。
怎么来解决这个问题呢?
Collection虽然可以存储各种对象,但实际上通常Collection只存储同一类型对象。例如都是存储字符串对象。
泛型:可以在类或方法中预支地使用未知的类型。
tips:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
详细概述
是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型。
分为泛型类、泛型方法、泛型接口。
泛型的好处
那么泛型带来了哪些好处呢?
将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
避免了类型强转的麻烦。
通过我们如下代码体验一下:
public class GenericDemo2 {public static void main(String[] args) {Collection<String> list = new ArrayList<String>();list.add("无鸡");list.add("无忌");list.add(5);//当集合明确类型后,存放类型不一致就会编译报错// 集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型Iterator<String> it = list.iterator();while(it.hasNext()){String str = it.next();//当使用Iterator<String>控制元素类型后,就不需要强转了。获取到的元素直接就是String类型System.out.println(str.length());}}
}
泛型的定义与使用
说明
我们在集合中会大量使用到泛型
泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
泛型类
格式:
修饰符 class 类名<代表泛型的变量> { }
Collection接口集合:
interface Collection<E>{ public boolean add(E e){ }...
}
使用泛型: 即什么时候确定泛型。
在创建对象的时候确定泛型
例如,Collection<String> list = new ArrayList<String>();
此时,变量E的值就是String类型,那么我们的类型就可以理解为:
interface Collection<String>{ public boolean add(String e){}...
}
自定义泛型类:
public class Generic<T> { private T t; public T getT() { return t; }public void setT(T t) { this.t = t; }
}
测试类:
public class Demo { public static void main(String[] args) { Generic<String> g1 = new Generic<String>(); g1.setT("ikun"); System.out.println(g1.getT()); Generic<Integer> g2 = new Generic<Integer>(); g2.setT(30); System.out.println(g2.getT()); Generic<Boolean> g3 = new Generic<Boolean>(); g3.setT(true); System.out.println(g3.getT()); }
}
泛型方法
格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
案例:
public class Generic { public <T> void show(T t) { System.out.println(t); }
}
测试类:
public class GenericDemo { public static void main(String[] args) { Generic g = new Generic(); g.show("无忌"); g.show(29); g.show(true); }
}
泛型接口
格式:
修饰符 interface 接口名<类型> { }
示例:
public interface Generic<T> { void show(T t);
}
泛型接口实现类:
public class GenericImpl<T> implements Generic<T> { @Override public void show(T t) { System.out.println(t); }
}
测试类:
public class GenericDemo { public static void main(String[] args) { Generic<String> g1 = new GenericImpl<String>(); g1.show("无忌"); Generic<Integer> g2 = new GenericImpl<Integer>(); g2.show(30); }
}
泛型通配符
说明
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符基本使用
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
代码理解如下:
public static void main(String[] args) {Collection<Intger> list1 = new ArrayList<Integer>();getElement(list1);Collection<String> list2 = new ArrayList<String>();getElement(list2);
}
public static void getElement(Collection<Integer> coll){//只能放Integer,不能放String}
public static void getElement(Collection<?> coll){}
1、通配符,代表未知类型,代表不关心或无法确定实际操作的类型,一般与容器类配合使用。
public void testV(List<?> list) {}
高级使用
说明
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限
上限
格式:
类型名称 <? extends 类 > 对象名称
意义:
只能接收该类型及其子类
下限
格式:
类型名称 <? super 类 > 对象名称
意义:
只能接收该类型及其父类型
案例
比如:现已知Object类,String 类,Number类,Integer类,其中Number是Integer的父类
class Parent{String name;
}
class Son extends Parent{int age;
}
public static void main(String[] args) {Collection<Parent> list1 = new ArrayList<Parent>();Collection<Son> list2 = new ArrayList<Son>();Collection<Object> list3 = new ArrayList<Object>();getElement1(list1);getElement1(list2);getElement1(list3);//报错getElement2(list1);getElement2(list2);//报错getElement2(list3);}
// 泛型的上限:此时的泛型?,必须是Parent类型或者Parent类型的子类
public static void getElement1(Collection<? extends Parent> coll){}
// 泛型的下限:此时的泛型?,必须是Parent类型或者Parent类型的父类
public static void getElement2(Collection<? super Parent> coll){}
谢谢观看啦 不懂可以看我的视频讲解
Java中的泛型讲解【最详细】【精美版】相关推荐
- [转载] 详解Java中的泛型
参考链接: Java中具有泛型的有界类型 1.什么是泛型 泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名 ...
- 聊聊Java中的泛型
聊聊Java中的泛型 文章目录 聊聊Java中的泛型 参考资料 一.概述 1. 泛型的定义 1.1 定义 1.2 常见形式 2. 为什么需要泛型 3. 泛型的优点 4. 泛型的使用 4.1 泛型类 4 ...
- Java 中的泛型(两万字超全详解)
文章目录 前言 一.泛型概述 1. 什么是泛型?为什么要使用泛型? 2. 泛型使用场景 3. 泛型概述小结 二.泛型类 1. 泛型类的定义 2. 泛型类的使用 三.泛型接口 四.泛型方法 1. 泛型方 ...
- java如何用反射把具体方法抽象_如何在Java 中使用泛型或反射机制对DAO进行抽象...
如何在Java 中使用泛型或反射机制对DAO进行抽象 发布时间:2020-11-26 16:07:42 来源:亿速云 阅读:80 作者:Leah 本篇文章为大家展示了如何在Java 中使用泛型或反射机 ...
- Java中创建泛型数组
Java中创建泛型数组 使用泛型时,我想很多人肯定尝试过如下的代码,去创建一个泛型数组 T[] array = new T[]; 当我们写出这样的代码时编译器会报Cannot create a gen ...
- Java中的泛型 --- Java 编程思想
前言 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...
- 【笔记】JAVA中的泛型和反射
泛型 Java的泛型是如何工作的?什么是类型擦除? ----泛型是通过类型擦除来实现的,编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息.例如List在运行时仅用一个Lis ...
- java定义list_我的Java Web之路59 - Java中的泛型
本系列文章旨在记录和总结自己在Java Web开发之路上的知识点.经验.问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人. 目录 介绍 再谈Java中的类型 为什么需要泛型? J ...
- java中的泛型(E)
java中的泛型(E) 泛型:就是一种不确定的数据类型. 比如:ArrayList E就是泛型. 这种不确定的数据类型需要在使用这个类的时候才能够确定出来. 泛型可以省略,如果省略,默认泛型是Obje ...
- Java中的泛型全解析(二)
Java中的泛型全解析(一) 泛型中的约束和局限性 现在我们有泛型类 不能用基本类型实例化类型参数 运行时类型查询只适用于原始类型 泛型类的静态上下文中类型变量失效 不能在静态域或方法中引用类型变量. ...
最新文章
- CATransition
- 正则表达式入门之字符匹配
- 这家AI公司用面具破解中国人脸识别系统!微信、支付宝、火车站无一幸免
- vscode自动格式化不符合eslint_VsCode(Visual Studio Code)格式化代码符合EsLint
- 一文读懂 | CPU负载均衡实现
- Style Report 培训开始啦!!
- CorelDRAWX4的VBA插件开发(十九)渲染显示开关
- 行癫:只有合作伙伴和客户成功,才是阿里云的成功
- CCleaner软件一键查找/删除重复文件
- 零基础实现摄像头的全平台直播 (一)内网直播的实现
- 1051 复数乘法(JAVA)
- 计算机专业硕士毕业论文,计算机技术专业硕士毕业论文(9)(喜欢就下吧)...
- Flink(Pometheus监控)
- 华为HCIE RS笔记-02分层
- Css3的旋转和位移
- 开一家洗车店需要购买哪些设备
- leetcode学习笔记之07Revers Integer(整数反转)
- select2 新增全选功能
- [篇五章四]-关于 Windows 10 没有桌面图标如何调出来
- 美国政府否认“口头批准”超级高铁,然而马斯克没有任何损失