5.2Java语言的泛型(Generic)

Java 集合有个缺点,就是把一个对象“丢进”集合里之后,集合就会“忘记”这个对象的数据类型,当再次取出该对象时,该对象的编译类型就变成了 Object 类型(其运行时类型没变)。

Java 集合之所以被设计成这样,是因为集合的设计者不知道我们会用集合来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,只要求具有很好的通用性,但这样做带来如下两个问题:

  1. 集合对元素类型没有任何限制,这样可能引发一些问题。例如,想创建一个只能保存 Dog 对象的集合,但程序也可以轻易地将 Cat 对象“丢”进去,所以可能引发异常。
  2. 由于把对象“丢进”集合时,集合丢失了对象的状态信息,集合只知道它盛装的是 Object,因此取出集合元素后通常还需要进行强制类型转换。这种强制类型转换既增加了编程的复杂度,也可能引发 ClassCastException 异常。

所以为了解决上述问题,从 Java 1.5 开始提供了泛型。泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。我们可以为类、接口或方法运用泛型,以下将介绍 Java 中泛型的使用。

List<Number> list = new ArrayList<Number>();
// 可以省略后面的Number,编译器可以自动推断泛型类型:
List<Number> list = new ArrayList<>();

泛型可运用于以下场景:

T、U和S:任意类型

E:集合的元素类型

K和V:键和值的类型

泛型类或接口

类型变量放在类名的后面。

class ClassName<T1, T2> {
    //类体
}
public class Pair<T> {

    private T first;
    private T second;

    public Pair() { 
        first = null;
        second = null;
    }

    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public T getSecond() {
        return second;
    }

    public void setFirst(T newValue) {
        first = newValue;
    }

    public void setSecond(T newValue) {
        second = newValue;
    }
}

泛型方法

类型变量放在修饰符的后面,并在返回类型的前面。

在方法中也可以使用泛型,即方法的参数类型或返回值类型,可以用类型参数表示。

修饰符 <T> T 方法名(T a, T b) {
    //方法体
}
class ArrayAlg {
    public static <T> T getMiddle(T...a) {
        return a[a.length / 2];
    } 
}

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/java/javabasic/2514.html

发表评论

登录后才能评论