Thinking in java-38 Java 泛型Generics in java

1. Generics 泛型引入

泛型是在Java 5 之后引入到java 语言中的,其目的是为了提供编译时类型检查,减少ClassCastException异常风险。容器参数化能力是当初Generic引入的一个主要动力,它将运行时异常ClassCastException在编译时就强制检查,如果类型不匹配将抛出一个编译时错误。

2. Generic Class泛型类

我们可以定义泛型类。泛型类型是一种具有参数化类型的类或接口,我们使用(<>)来指定这种类型参数。

package com.fqy.generic;

public class GenericClass<T> {
    private T t;

    public void add(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    public static void main(String[] args) {
        GenericClass<Integer> intClass = new GenericClass<>();
        GenericClass<String> strClass = new GenericClass<>();

        intClass.add(10);
        strClass.add("Hello sdy");

        System.out.println("Integer value: " + intClass.get());
        System.out.println("String value: " + strClass.get());
    }

}
//Running result:
Integer value: 10
String value: Hello sdy

3. 泛型方法Generic Method

有时,我们并不想参数化整个类,这时,我们可以选择创建泛型方法。因为构造函数是一种特殊的方法,所以我们可以在构造函数中使用泛型。

package com.fqy.generic;

public class GeMethod {
    // Determine the largest of three Comparable objects
    public static <T extends Comparable<T>> T maxInThree(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;
    }

    public static void main(String[] args) {
        System.out.printf("Max of %d %d %d is %d\n", 3, 4, 5, maxInThree(3, 4, 5));
        System.out.printf("Max of %.1f %.1f %.1f is %.1f\n", 8.9, 4.7, 5.6, maxInThree(8.9, 4.7, 5.6));
        System.out.printf("Max of %s %s %s is %s\n", "pear", "apple", "banana", maxInThree("pear", "apple", "banana"));

    }

}
//Running result:
Max of 3 4 5 is 5
Max of 8.9 4.7 5.6 is 8.9
Max of pear apple banana is pear

4. 有限制的类型参数

  • 泛型通配符:’?’是泛型通配符,并代表了一种未知的类型。该通配符可以用作参数、数据域、局部变量的类型,有时被用于返回值。在我们调用泛型方法或实例化一个泛型类时,我们不能使用通配符。
  • 泛型上界通配符:上界通配符是用来松弛方法中变量类型的限制。
//A method to return the sum of a list
public double sum(List<Number> list){
    double sum = 0;
    for(Number n: list)
        sum += n.doubleValue();
    return sum;
}

//上述代码问题时,对于List<Integer> & List<Double>上述方法就不适用了,这个时候就需要上界通配符了。
public double sum(List<? extends Number> list){
    double sum = 0;
    for(Number n: list)
        sum += n.doubleValue();
    return sum;
}
  • 泛型无界通配符: 有时,我们希望我们的泛型方法适用于所有的类型,这时无界的通配符就可以使用了, 和使用
public void printData(List<?> list){
    for(Object obj: list)
        System.out.println(obj+" ");
}
  • 泛型下界通配符:假设我们想要添加整形数据到一个整形的list中,我们可以设置参数为 List,但是这将限制了一些类型,因为List和 List也可能有整形数据,这时我们就可以用下界通配符达到这个目的了。
public void addIntegers<List<? super Integer> list){
    list.add(new Integer<50>);
}

5. Java泛型类型擦除机制

java中的泛型引入只是为了提供一种编译时类型检测机制,其在运行时没有任何作用;所以java编译器使用类型擦除机制来移除所有的类型检测代码,并在必要时候插入类型转换。类型擦除保证了没有为参数化类型创建新类;相应的,泛型不会招致人和运行时开销。
另:

 //Error: generic doesn't support sub-typing
 List<Number> numbers = new ArrayList<Integer>();
 //Error: we can't create generic array.
 List<Integer>[] array = new ArrayList<Integer>[10];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值