2022-10-19
泛型 类型 问题
泛型的横空出世
1. 为什么引入泛型/引入泛型的必要性
来,我们深入分析下上述代码运行时出现错误的主要原因:
ArrayList的本质是一个Object数组Object[] elementArr,这种设计虽然体现出来了泛型的思想(泛型:泛指任意类型),但是有以下问题:
ArrayList实例化之后,可以随意添加任意类型的对象(Obeject是任意引用类型的基类)。
获取元素的前提是:需要提前知道列表元素的类型。
获取列表元素时然后进行操作,都需要进行显式类型转换,容易发生类型转换出错的问题。
由于早期我们开发者经常操作集合对象,所以频繁的出现运行期间异常问题,这种问题困扰了很多人,SUN官方的设计师们也下定决心解决这个问题,这些大佬们在想: 如果集合能和数组一样,在定义时就指定好类型,这样就不会出现运行期间异常问题了,也就规避了很多安全隐患。
所以SUN官方提出了泛型技术来解决操作集合中存在的这些问题。
2. 泛型的引入时机
SUN官方在推出jdk1.5版本时,就对这样的问题提出了解决方案: 泛型。
泛型的由来:通过Object转型问题引入 ,早期的Object类型可以接收任意的对象类型,泛型其实指的就是任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
所以后期SUN官方的这些大佬们,对泛型的设计核心思想就两条:
在定义时,泛型可以指任意的对象类型。
在使用时,必须明确泛型的具体对象类型。
来我们看一下,SUN官方jdk1.5之后,对List集合的改造:
/**
* @param <E> the type of elements in this list: 定义List时,E可以指代任意对象的类型
*/
public interface List<E> extends Collection<E> {
----------
}
下面我们看一下List的使用:
public class GenericsDemo {
public static void main(String[] args) {
//1.创建一个List对象:指定泛型为String
List<String> list = new ArrayList<String>();
//2.向List中添加数据:必须添加String类型的数据
list.add("corn");
list.add("java");
//3.遍历集合
for (int i = 0; i <list.size() ; i++) {
//4.把集合中的每个元素转成String类型
String ele = (String) list.get(i);
//5.打印-测试结果
System.out.println("元素的值:"+ele);
}
}
}
那么如果我们使用 Listlist 添加其它类型的数据呢?
可以看到下图:不允许添加除String类型以外的,其它类型的数据,这样后期操作就不会有问题了。
小伙伴,我们来简单的总结一下:
虽然泛型在定义时可以表示任意对象的类型,但是我们在使用是,必须明确泛型指代的具体类型,那么就这么一点小小的改动带来的确实本质性的变化: 一劳永逸,体现了泛型的通用性,规避了很多安全问题。
3. 泛型能做的哪些事
经过我们刚才的"一顿分析与操作",小伙伴应该基本清楚了泛型能够解决那些问题了。
jdk1.5之后加入泛型,主要是为了解决类型转换的安全隐患,具体体现如下:
解决泛型对象实例化之后,可以随意添加任何类型的对象的问题。
解决获取泛型元素前,需要提前确定元素的类型的问题。
解决获取元素时,需要进行显式类型转换的问题。
解决容易出现类型转换出错的问题。
那么小伙伴们,我们通过下面代码来细细品味一番:
public class GenericsDemo2 {
public static void main(String[] args) {
//1.创建一个泛型为String的集合: 解决泛型对象实例化之后,可以随意添加任何类型的对象的问题。
List<String> list = new ArrayList<String>();
//2.向List中添加String类型的数据:解决获取泛型元素前,需要提前确定元素的类型的问题。。
list.add("corn");
list.add("java");
//list.add(66);//报编译错误:不能添加int型的数据
//3.遍历集合
for (int i = 0; i <list.size() ; i++) {
//4.把集合中的每个元素:解决获取元素时,需要进行显式类型转换的问题。
String ele = list.get(i);// 不需要类型强转:解决容易出现类型转换出错的问题。
//5.打印-测试结果
System.out.println("元素的值:"+ele);
}
}
}
其实看完这些代码后,想必小伙伴心中都有了一个明确的答案:
之前我们没有使用泛型操作集合,可以添加任意类型的数据,在后期运行代码时,进行类型转换就会出问题。
如果我们使用了泛型,那么在添加数据时,如果添加的数据类型不对,编译就会出问题,更不用说后期运行了。
所以我们用一句话总结泛型:
泛型主要是将运行期间的异常问题,转移到编译期间来体现,避免了类型强制转换的问题。
闯关练习
需求:创建一个指定泛型为Integer的Set集合,添加数字1到100,取出里面的偶数。
答案:
public class GenericsDemo3 {
public static void main(String[] args) {
//1.创建一个泛型为Integer的集合
Set<Integer> numbers = new HashSet<Integer>();
//2.向set集合中添加数字:1-100
for (int i = 1; i <=100 ; i++) {
numbers.add(i);
}
//3.遍历set集合,获取里面的偶数并打印
for (Integer elementData : numbers) {
//4.条件判断:
if(elementData%2==0){
//5.打印测试:
System.out.println("偶数是:"+elementData);
}
}
}
}
开班时间:2021-04-12(深圳)
开班盛况开班时间:2021-05-17(北京)
开班盛况开班时间:2021-03-22(杭州)
开班盛况开班时间:2021-04-26(北京)
开班盛况开班时间:2021-05-10(北京)
开班盛况开班时间:2021-02-22(北京)
开班盛况开班时间:2021-07-12(北京)
预约报名开班时间:2020-09-21(上海)
开班盛况开班时间:2021-07-12(北京)
预约报名开班时间:2019-07-22(北京)
开班盛况Copyright 2011-2023 北京千锋互联科技有限公司 .All Right 京ICP备12003911号-5 京公网安备 11010802035720号