Java JDK1.5: 泛型 新特性的讲解说明
每博一文案
听到过这样一句话:“三观没有标准。在乌鸦的世界里,天鹅也有罪。”
环境、阅历的不同,造就了每个人独有的世界观、人生观、价值观。
三观并无对错高下,只有同与不同。恰如飞鸟不用和游鱼同行,高山不必同流水相逢。
总用自己的尺子去度量别人,无疑是一种狭隘。面对不同时,只有懂得尊重对方,才能跳出固有的认知,看得更高更远。
这个世界上没有标准答案,人不是只有一种活法。
@
1. 泛型概述
在任何不重要的软件项目中,错误都只是生活中的事实。 仔细的计划,编程和测试可以帮助减少他们的普遍性,但不知何故,在某个地方,他们总是会找到一种方法来进入你的代码。 随着新功能的推出以及您的代码库规模和复杂性的增加,这一点变得尤为明显。
幸运的是,一些错误比其他错误更容易被发现。例如,编译时错误可以在早期发现; 你可以使用编译器的错误信息来找出问题所在,然后修正它。运行时错误,然而,可能是更多的问题; 它们并不总是立即出现,而且当它们这样做时,它可能在程序中的某一点远离问题的实际原因。
泛型通过在编译时检测更多的错误来增加代码的稳定性。
- 泛型的设计背景
集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为 Object,JDK1.5 之后使用泛型来 解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于 这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。Collection,List,ArrayList 这个就是类型参数,即泛型。
- 泛型的概述
- 所谓的泛型,就是允许在定义类,接口时通过一个标识
<T>
类中某个属性的类型或者时某个方法的返回值以及参数类型。或者换句话说:就是限定类/接口/方法(参数/返回值)的类型。特别的就是限定集合中存储的数据类型。这个类型参数将在使用时(例如:继承或实现这个接口,用这个类型声明变量,创建对象时) 确定(即传入实际的类型参数,也称为 “类型实参”)。 - 从 JDK1.5 以后,java 引入了 “参数化类型 (
Parameterized type
)” 的概念,允许我们在创建集合时再指定集合元素的类型,正如: List<String> ,这表明该 List 集合只能存储 字符串String类型的对象 。 - JDK1.5 改写了集合框架中全部接口和类,为这些接口,类增加了泛型支持,从而可以在声明集合变量,创建集合对象时传入 类型实参。
- 所谓的泛型,就是允许在定义类,接口时通过一个标识
2. 为什么要使用泛型
那么为什么要有泛型呢,直接Object 不是也可以存储数据吗?
- 解决元素存储的安全性问题,好比商品,药品标签,不会弄错
- 解决获取数据元素时,需要类型强制转换的问题,好比不用每回拿药,药品都要辨别,是否拿错误。
如下举例:
没有使用泛型
我们创建一个 ArrayList 集合不使用泛型,默认存储的是 Object 类型,用来存储 学生的成绩 int 类型,添加成绩时不小心添加了
学生的姓名,因为该集合没有使用泛型,默认是Object 类型,什么都可以存储,所以也把这个输入错误的 学生姓名给存储进去了。
当我们把 ArrayList 集合当中的存储的数据取出 (强制转换为 int 类型的数据成绩时),报异常:java.lang.ClassCastException
类型转换异常。因为你其中集合当中存储了一个学生的姓名,String 是无法强制转换成 int 类型的。
import java.util.ArrayList;
public class GenericTest {
// 没有使用泛型
public static void main(String[] args) {
// 定义了泛型没有使用的话,默认是 Object 类型存储
ArrayList arrayList = new ArrayList();
// 添加成绩
arrayList.add(99);
arrayList.add(89);
arrayList.add(79);
// 问题一:存储的类型不安全
// 不小心添加了一个学生的姓名
arrayList.add("Tom");
for (Object o : arrayList) {
// 问题二: 强转时,可能出现ClassCastException 异常
int stuScore = (Integer)o; // 因为你存储的类型可能与强制转换的类型,没有继承关键,实例关系
// 导致转换失败.
System.out.println(stuScore);
}
}
}
使用了泛型
将 ArrayLsit 集合定义为 ArrayList<Integer>
使用上泛型,限定了该集合只能存储 Integer 类型的数据,其它类型的无法存入进到集合当中,编译的时候就会报错。
import java.util.ArrayList;
public class GenericTest {
// 使用上泛型
public static void main(String[] args) {
// 泛型限定了存储类型,泛型指定定义引用类型,基本数据类型不行
ArrayList<Integer> arrayList = new ArrayList<Integer>();
// 使用了泛型: 就会进行类型检查,保证数据的安全
arrayList.add(99); // 包装类,自动装箱
arrayList.add(78);
arrayList.add(76);
arrayList.add(89);
arrayList.add(88);
// arrayList.add("Tom"); // 存储不符合泛型的数据,编译无法通过。
for (Integer integer : arrayList) {
int stuScore = integer; // 不需要强制转换自动拆箱
System.out.println(stuScore);
}
}
}
Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生 java.lang.ClassCastException
异常。同时代码更加简洁,健壮 。
简而言之,在定义类,接口和方法时,泛型使 类型(类和接口)成为参数。 就像方法声明中使用的更熟悉的 形式参数 一样,类型参数为您提供了一种方法, 让您在不同的输入中重用相同的代码。区别在于形式参数的输入是值,而类型参数的输入是类型。
使用泛型的代码比非泛型代码有许多优点:
-
编译时更强大的类型检查。
Java