当前位置: 首页 / 技术干货 / 正文
民哥带你快速精通java泛型(二)

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类型以外的,其它类型的数据,这样后期操作就不会有问题了。

a2

  小伙伴,我们来简单的总结一下:

  虽然泛型在定义时可以表示任意对象的类型,但是我们在使用是,必须明确泛型指代的具体类型,那么就这么一点小小的改动带来的确实本质性的变化: 一劳永逸,体现了泛型的通用性,规避了很多安全问题。

  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);
}
}
}
}

好程序员公众号

  • · 剖析行业发展趋势
  • · 汇聚企业项目源码

好程序员开班动态

More+
  • HTML5大前端 <高端班>

    开班时间:2021-04-12(深圳)

    开班盛况

    开班时间:2021-05-17(北京)

    开班盛况
  • 大数据+人工智能 <高端班>

    开班时间:2021-03-22(杭州)

    开班盛况

    开班时间:2021-04-26(北京)

    开班盛况
  • JavaEE分布式开发 <高端班>

    开班时间:2021-05-10(北京)

    开班盛况

    开班时间:2021-02-22(北京)

    开班盛况
  • Python人工智能+数据分析 <高端班>

    开班时间:2021-07-12(北京)

    预约报名

    开班时间:2020-09-21(上海)

    开班盛况
  • 云计算开发 <高端班>

    开班时间:2021-07-12(北京)

    预约报名

    开班时间:2019-07-22(北京)

    开班盛况
IT培训IT培训
在线咨询
IT培训IT培训
试听
IT培训IT培训
入学教程
IT培训IT培训
立即报名
IT培训

Copyright 2011-2023 北京千锋互联科技有限公司 .All Right 京ICP备12003911号-5 京公网安备 11010802035720号