泛型的本质:参数类型化
概述:将类型由原来的具体的类型参数化,然后在 使用/调用 时传入具体的类型
格式:
好处:
把运行时期的问题提前到了编译期间
import java.util.ArrayList;
import java.util.Collection;
public class Test{
// 遍历集合
public static void show(Collection co){
for(Object c : co){
System.out.println(c);
}
}
public static void main(String args[]){
// 1、创建集合对象,Collection 是接口,所以创建对象只能用其子类实现类
Collection c = new ArrayList();
// 2、添加元素
c.add(1);
c.add("张三");
c.add(true);
// 3、遍历集合
show(c);
}
}
注意:我们可以看到,此时的 Collection 集合可以添加任意数据类型,但是大家思考一个问题,集合中存储不同数据类型,是否会影响我们后期对于集合中数据的操作呢?答案是肯定的,怎么解决呢,我们就可用到泛型。
这样,我们就可以将 问题 提前到了 编译期间!
避免了强制类型转换
格式: 修饰符 class 类名<参数类型>{}
// 学生泛型类
class Student<T>{
private T value; // 定义私有变量
public Student(T value){
this.value = value;
}
public T getValue(){
return value;
}
public void setValue(T value){
this.value = value;
}
}
// 测试类
public class Test1{
public static void main(String args[]){
// 这里的 <> 中 String 和 Integer 是实参,T 是形参
Student<String> s1 = new Student<String>("张三");
Student<Integer> s2 = new Student<Integer>(1);
System.out.println(s1.getValue() + " " + s2.getValue());
}
}
最终运行结果:张三 1
格式:修饰符 <类型> 返回值类型 方法名(类型 变量名){}
class Cat{
// 泛型方法
public <T> T show(T t){
return t;
}
}
public class Test{
public static void main(String args[]){
// 1、创建对象
Cat t = new Cat();
// 2、调用泛型方法,传入不同的参数
String s = t.show("张三");
int i = t.show(1);
System.out.println(s + " " + i);
}
}
最终运行结果:张三 1
格式:修饰符 interface 接口名 <类型>{}
interface Animal<T>{
// 抽象方法
public void show(T t);
}
// 实现 泛型接口
class Dog implements Animal<String>{
@Override
public void show(String s) {
System.out.println(s);
}
}
public class Test{
public static void main(String[] args) {
Dog d = new Dog();
d.show("李四");
}
}
类型通配符:<?>
例如:List<?>:表示元素类型未知的List,他的元素可以匹配任何的类型
这种带通配符的List仅表示它是各种泛型的List的父类,并不能把元素添加到其中
范围 | 格式 | 举例 | 作用 |
---|---|---|---|
任意类型 | <?> | List<?> | 表示的类型是所有 |
上限 | <? extends 类型> | List<? extends Number> | 表示的类型是Number或者其子类 |
下限 | <? super 类型> | List<? super Number> | 表示的类型是Number或者其父类 |