Java集合框架02:泛型
泛型的本质是参数化类型,把类型作为参数传递
在语法上,<T...>表示类型占位符,只能是引用类型。T可以创建非静态变量(不能赋值)、作为方法的参数、作为方法的返回值类型,但是不能实例化对象(因为如果不知道要实例化的类是什么,那就不知道它是否有一个构造函数)
泛型类
public class Hello{
public static void main(String[] args) {
//泛型只能是引用类型,当指定为Integer类型后,就只能赋值这种类型,不同的类型不能相互赋值
Generic<Integer> i = new Generic();
i.t = 1;
System.out.println(i.getT());
Generic<String> s = new Generic();
s.t = "Hello";
System.out.println(s.getT());
}
}
//创建一个泛型类
class Generic<T>{
//创建泛型变量,因为不确定类型,故不能赋值,也不能创建静态变量
T t;
//作为方法的参数
public void test(T t){
System.out.println("t");
}
//作为方法的返回值类型
public T getT(){
return t;
}
}
泛型接口
public class Hello{
public static void main(String[] args) {
Son a = new Son();
//实现接口时不确定,实例化时就要指定类型,右边的new语句可以不写泛型或空着,但左边必须写
Son1<Integer> b = new Son1<>();
}
}
//创建一个泛型接口
interface Test<T>{
String name = "ty";
T test(T i);
}
//子类可以在实现接口时确定类型
class Son implements Test<String>{
@Override
public String test(String i) {
return null;
}
}
//也可以实现接口时不确定类型,实例化时再确定,此时子类也要加上泛型占位符
class Son1<T> implements Test<T>{
@Override
public T test(T i) {
return null;
}
}
泛型方法
public class Hello{
public static void main(String[] args) {
Hello a = new Hello();
//调用泛型方法时,传入什么参数,就会变成什么类型
a.test("String");
a.test(1);
}
//创建泛型方法,<T>放在返回值类型前
public<T> T test(T t){
System.out.println(t);
return t;
}
}
泛型集合
泛型集合,是一种参数化类型、类型安全的集合,强制集合元素的类型必须一致
ArrayList等类其实是泛型类,在没有指定类型时,所有的元素都会转换成Object类型,这不利于转换为原来的类型,推荐创建同一类型的泛型集合对象
import java.util.ArrayList;
import java.util.Iterator;
public class Hello{
public static void main(String[] args) {
ArrayList<String> s = new ArrayList<>();
ArrayList<Integer> i = new ArrayList<>();
//泛型集合指定了数据类型以后,只能添加同种类型
s.add("String");
i.add(1);
//迭代器也会转为相应的类型
Iterator<Integer> it = i.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
泛型集合的特点:
- 编译时检查,而不是等到运行时抛出异常
- 访问时,不必进行类型转换
- 不同泛型之间引用不能相互赋值,不存在多态
泛型的优点
-
提高代码的重用性,不用重载就可以在同一个方法传入不同类型的参数
-
防止类型转换异常,提高代码的安全性