一、泛型
泛型,JDK1.5后推出的新特性,参数化类型可以允许在使用时指定类型。泛型可以解决数据类型的安全性问题,它的主要原理是:在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。
(1)泛型可以修饰属性、方法参数以及返回值类型。
(2)集合中也使用了泛型,用来约束存入集合的元素类型。
(3)迭代器也支持泛型,用来指定其遍历的集合的元素类型。迭代器的泛型与集合指定的泛型一致即可。
泛型传入的必须是包装类型,或者是自定义的类,不能传入基本类型例。
①注:将泛型改为基本数据类型的时候,编译器为什么报错了?
原来,泛型必须是包装类类型,也就是只能代表引用类型,而不能是基本数据类型,也就是不能是原始数据类型,比如 long / int / short / byte / double / float / boolean / char ,这些都是不能被引用了。
②注:为什么需要包装类?
因为在程序中,有些结果有些数据可能会返回空值,转化为基本数据类型比如 int 就会发生异常,因为类似于 int 这些是没有 null 值可言的。但是基本数据类型对应的如 Integer 这些包装类类型就不会,因为对象可以为 null 值。
③注:为什么又要有基本数据类型?
这主要是基于程序性能的考量的,基本数据类型的定义是存放在栈中的,但是我们创建对象而引出来的实际数值则是放在堆里的,堆的速度远远不如栈。而且基本数据类型变量的创建和销毁都非常快,而类定义的变量还需要 JVM 去销毁。没错,就是因为考量了程序性能的问题。
(参考:Java之泛型再学习为什么泛型会报错?为什么需要包装类?为什么又要有基本数据类型?)
二、格式
访问权限 class 类名称<泛型,泛型...>{
属性
方法
}
三、对象的创建
类名称<具体类型> 对象名称 = new 类名称<具体类型>();
四、构造方法中使用泛型
package com.haobi;
/*
* 构造方法中使用泛型
*/
class C<T>{
private T value;
public C(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
public class Test {
public static void main(String[] args) {
C<String> c = new C<String>("构造方法中使用泛型");
System.out.println(c.getValue());
}
}
//程序输出结果如下:
构造方法中使用泛型
五、泛型接口
//格式
interface 接口名称<泛型标准>{}
(1)HashSet集合
HashSet是Set接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的。Hashset根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存储和查找性能。
(2)TreeSet集合
TreeSet则是以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序。
(3)Map接口
Map接口是一种双列集合,它的每个元素都包含一个键对象key和值对象value,键和值对象之间存在一种对应关系,称为映射。从Map集合中访问元素时,只要指定了key,就能找到对应的value。
(4)HashMap集合
HashMap集合是Map接口的一个实现类,它用于存储键值映射关系,但必须保证不出现重复的键。
(5)HashTable集合
HashTable和HashMap十分相似,区别在于HashTable是线程安全的。
六、泛型的优点
Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其他类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。它也给运行时带来好处,因此不会产生类型检查的字节码指令。