Java泛型学习总结

Java泛型

泛型提供了编译时类型安全检测机制,允许程序员在编译时检测到非法的类型

本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
 
泛型最⼤的好处是可以提⾼代码的复⽤性。
以List接⼜为例,我们可以将String、 Integer等类型放⼊List中,
如不⽤泛型, 存放String类型要写⼀个List接口, 存放Integer要写另外⼀个List接口,
泛型可以很好的解决这个问题

泛型方法

1)方法在调用时可以接收不同类型的参数,根据传递的数据类型,调用相对应的数据方法,可以说是C++的模板
定义泛型方法的规则:
.1所有泛型方法申明都以一个类型参数声明部分<>,声明在方法返回类型之前
.2类型参数声明包含一个多个参顺类型.中间逗号隔开.泛型参数=泛型变量,指定一个泛型类型名称的标识符
.3类型参数可声明返回类型,可作为泛型方法得到的实参类型占位符
.4类型参数只能代表引用型类型,不能替代原始类型

实例一:
使用泛型方法打印不同字符串的元素
//泛型方法
    public static <E> void printArray(E[] Array){
    // 输出数组元素
        for (E element:Array) {
            System.out.print(element+" ");
        }
        System.out.println(" ");
    }
    
2)有界的类型参数
限制特定类型的数值传入到特定区域.比如只希望接受Number或者Number子类的实例
步骤:
首先列出类型参数的名称,后跟extends关键字,最后紧跟它的上界
实例二:
返回三个可比较对象的最大值
public static <T extends Comparable<T>> T maximum(T x,T y,T z){
        T max=x;
        if(y.compareTo(max)>0){
            max=y;
        }
        if(z.compareTo(max)>0){
            max=z;
        }
        return max;
    }
给我的感觉就是c++里的模板,虽然 c++的模板更难,也更抽象,但实际应用更广.

泛型类

在类名后面添加了类型参数声明部分
泛型类的类型参数声明部分包含多个类型参数,彼此逗号隔开,
泛型参数=泛型变量,用于指定一个泛型类型名称的标识符
例子:
定义一个泛型类
public class GenericClass <T>{
    private T t;
    public void Add(T t){
        this.t=t;
    }
    private T get(){
        return t;
    }
    public static void main(String[] args) {
      GenericClass<Integer> interGen=new GenericClass<Integer>();//限制了只有Integer类型的
      GenericClass<String> StringGen=new GenericClass<String>();
      interGen.Add(new Integer(100));
      StringGen.Add(new String("沐汐语,我喜欢你!"));
      System.out.println("整型值为 :\t"+interGen.get());
      System.out.println("字符串为:\t"+StringGen.get());
    }
}

类型通配符

类型通配符一般是使用?代替具体的类型参数
List<?>  在逻辑上是 List<String>,List<Integer>  等所有List <具体类型实参>的父类
main方法内
List<String> name=new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        name.add("沐汐语");
        age.add(22);
        number.add(2324);
//获取集合中的数据
        getData(name);
        getData(age);
        getData(number);
简单的通配符:
    public static void getData(List<?> data){
        System.out.println("data :" + data.get(0));
    }
输出结果:
测试通配符
data :沐汐语
data :22
data :232
类型通配符上限通过形如List<? extends Number> 来定义,通配符泛型值接受Number及其下层子类类型
类型通配符下限通过形如 List<? super Number>来定义类型只能接受Number及其三层父类类型

上下界限定符extends 和 super

<? extends T>和<? super T>是Java泛型中的“通配符(Wildcards)”和“边界(Bounds)”的概念
<? extends T>:是指 “上界通配符(Upper Bounds Wildcards)”
即泛型中的类必须为当前类的子类或当前类。
<? super T>:是指 “下界通配符(Lower Bounds Wildcards)”
即泛型中的类必须为当前类或者其父类。
例子:
import java.util.List;
class Food {}
class Fruit extends Food {}
class Apple extends Fruit {}
class Banana extends Fruit{}
public class GenericTest {
    //用来测试上街通配符和下界通配符的实例.
public void testExtends(List<? extends Fruit> list){
    //报错,extends为上界通配符,只能取值,不能放.
    //因为Fruit的子类不只有Apple还有Banana,
    // 这里不能确定具体的泛型到底是Apple还是Banana
    // 所以放入任何一种类型都会报错
    //list.add(new Apple());
    Fruit fruit=list.get(1);
}
public void testSuper(List<? super Fruit>list){
    //super为下界通配符,可以存放元素
    //但是只能存放当前类或者子类的实例
    list.add(new Apple());
    //无法确定Fruit的父类是否只有Food一个(Object是超级父类)
    //list.add(new Food());
    Object object = list.get(1);
}
}
testExtends方法:
泛型中用的是extends,在向list中存放元素时,不确定List内的具体类型,无论传入什么都会出错
testSuper方法:
不能确定testSuper方法的参数中的泛型是Fruit的哪个父类,调用get方法时只能返回Object类型
返回超级父类不会报错

 

 

posted @ 2020-04-17 14:20  北斋汐语录  阅读(149)  评论(0)    收藏  举报