泛型类与泛型方法

泛型类

泛型类的声明

interface List 和 class GenTest<K,V> 其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以。 常用T表示,是Type的缩写。

泛型类的实例化

一定要在类名后面指定类型参数的值(类型)。如:

List<String> strList = new ArrayList<String>();
Iterator<Customer> iterator = customers.iterator();

jdk1.7,泛型的简化操作(类型推断),上述第一行代码可改为:

List<String> strList = new ArrayList<>();

自定义泛型类

public class Order <T>{
    private String name  = "";
    private int    price = 0;
    private T number;

    public Order() {
    }

    public Order(String name, int price, T number) {
        this.name = name;
        this.price = price;
        this.number = number;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public T getNumber() {
        return number;
    }

    public void setNumber(T number) {
        this.number = number;
    }
}

// 实例化
Order<Long> order = new Order<>("旺仔牛奶", 3.5, 43223425436452L);

注意事项

1.泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1,E2,E3>、<T,U,E>

2.泛型类的构造器不含泛型参数:

public Order() {} // 正确
public Order<T> {}  // 错误

3.实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。

4.泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。经验:泛型要使用一路都用。要不用,一路都不要用。

5.如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。

6.在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法中不能使用类的泛型。因为泛型类的类型参数实在实例化类时传递的,而静态方法时属于类的,不属于实例方法。

7.异常类不能是泛型的

8.父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型还可以增加泛型类型。

class Father<T1, T2> {
}

// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2 extends Father<Integer, String> {
}

// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> {
}
=======================================================
class Father<T1, T2> {
}

// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son<A, B> extends Father{//等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2<A, B> extends Father<Integer, String> {
}

// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2, A, B> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2, A, B> extends Father<Integer, T2> {
}

类型方法

声明格式

[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常

class ArrayListUnit
{
    public static <T> ArrayList<T> arrayListAdd (T ...elements)
    {
        ArrayList<T> ts = new ArrayList<>();

        for (T e : elements) {
            ts.add(e);
        }

        return ts;
    }
}

// 测试代码如下
ArrayList<String> list = ArrayListUnit.arrayListAdd(
    "php",
    "java",
    "c++", 
    "golang"
);
System.out.println(list); // [php, java, c++, golang]