为什么要用泛型?
编程中我们会遇到因为参数类型不同而导致我们多次对一个方法进行重载,然而有时候并不涉及参数个数之类的重载,此时会不会有更方便的方法呢?
在介绍泛型之前我们需要了解一个知识点,在java.lang(就是平时默认使用的包,不需要导包)下,有一个根类我们称之为祖宗类——object,关于此类详情可见api文档,我们需要了解的是所有属于lang包下的类都继承了该类。那么我们就可以根据这一点来写我们的代码。
显示传入的两个数字:可能为int,可能为double,可能为byte,可能为float型,也可能一个为int,一个为double,如果要写这样的一个方法,我需要进行无数次的(夸张了)函数重载。。。。
public class Demo {
public static void show(int a,int b){
System.out.println(a);
System.out.println(b);
}
public static void show(double a,int b){
System.out.println(a);
System.out.println(b);
}
public static void show(float a,int b){
System.out.println(a);
System.out.println(b);
} public static void show(int a,byte b){
System.out.println(a);
System.out.println(b);
}
}
这时我们可以使用到泛型来帮我们解决问题了
public class Demo {
public static void show(Object a,Object b){
System.out.println(a);
System.out.println(b);
}}
现在我先在该类中写一个junit测试一下结果
大家可以看见,虽然我传入的参数类型不同,但是却可以得到对应类型的结果,并且我的方法也只对了一次,这就是使用泛型的方便之处。接下来我要说几个泛型常用的场景。
1.使用集合时(使用已经定义好的泛型类创建对象)
当我们用Arrylist存储数据时,有时会不确定我们要存储的数据类型,这时候我们就可以使用泛型
public class test {
public static void main(String[] args) {
Collection<Object> collections=new ArrayList<>();
collections.add("根本不会java");
collections.add(2);
collections.add(2.0);
Iterator<Object> iterator = collections.iterator();
while(iterator.hasNext()){
Object o=iterator.next();
System.out.println(o);
}
}
}
此时我们使用多态的原理创建一个集合对象,然后往里面存String,int,double类型的数据,最后使用迭代器遍历集合
可以看到,我们输出的结果也是三种不同类型
当然了,以后我们可以不使用泛型,而是采用反射原理,调用类加载器完成这种多类型存储
2.实现接口(自定义泛型)
第一步,先定义一个泛型接口,并写一个含有泛型的抽象方法供实现此接口的类重写
public interface myFanxing<E> {
abstract void show(E e);
}
注意:一般应用时,我们使用一个大写字母表示使用的是泛型,相同的小写字母表示该泛型的参数,具体类型可以在创建对象或者方法重写时确定,并且泛型要用尖括号包裹
第二步,写一个类实现该接口,并重现其中的抽象方法,并给泛型确定类型
public class Demo implements myFanxing<String>{
@Override
public void show(String s) {
System.out.println(s);
}
}
此时泛型已经被确定为String类型,接下来我们继续使用junit进行测试
而且因为我们使用的是泛型接口,就算需要接收不同的参数类型,我们可以根据需求多来几个实现类就行。
3.泛型通配符
不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
但是此时我们就只能使用Object类中的共性方法,并且只能接收数据。
泛型中可以指定一个泛型的上限和下限
泛型的上限:
- 格式: 类型名称 <? extends 类 > 对象名称
- 意义: 只能接收该类型及其子类
泛型的下限:
- 格式: 类型名称 <? super 类 > 对象名称
- 意义: 只能接收该类型及其父类型