为什么要用泛型

在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。

对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。

规则限制:
1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2、泛型的类型参数可以有多个。

基于方法的泛型
public class GenericDemo{
    public static void main(String[] args) {
        GenericDemo genericDemo = new GenericDemo();
        genericDemo.print("luo");
        genericDemo.print(90);
    }
    //通常在返回值前跟泛型修饰符,T 不是固定的,可以随意取
    public<T> void print(T t){
        System.out.println(t);
    }
}
//可以同时支持多个泛型
public interface Function<T, R> {
    R apply(T t);
}
基于类的泛型

在类中多次用到同一个泛型,就可以定义在类上

public class GenericDemo<T>{
    public static void main(String[] args) {
        GenericDemo<Integer> genericDemo = new GenericDemo<>();
        Integer[] array = {1,1,2,5};
        genericDemo.printArray(array);
    }

    public void printArray(T[] t){
        Stream.of(t).forEach(System.out::println);
    }
    public void add(T t){
        System.out.println(t);
    }
}

注意:静态方法不能使用泛型类上定义的泛型

基于接口的泛型
public interface MyInterface<T> {
    public void add(T t);
}
public class MyInterfaceImpl<T> implements MyInterface<T> {
    @Override
    public void add(T t) {
	
    }
}

public class Test01 {
    public static void main(String[] args) {
        MyInterfaceImpl<Integer> integerMyInterface = new MyInterfaceImpl<>();
        MyInterfaceImpl<String> integerMyInterface2 = new MyInterfaceImpl<>();
        integerMyInterface.add(32);
        integerMyInterface2.add("luo");
    }
}

注意:泛型的类型只能是引用类型或自定义类型

泛型的高级应用

<? extends E> :向下限定,E及其子类

<? super E> :向上限定,E及其父类

<?> :任意类型


public class Animal {}
public class Cat extends Animal{}
public class Dog extends Animal {}

public class Test01 {
    public static void main(String[] args) {
        Collection <? extends Animal> collection1 = new ArrayList<Dog>();
        Collection <? extends Animal> collection2 = new ArrayList<Cat>();
        Collection <? extends Animal> collection3 = new ArrayList<Animal>();
        Collection <? super Animal> collection4 = new ArrayList<Object>();
        Collection <? super Animal> collection5 = new ArrayList<Animal>();
        Collection <?> collection6 = new ArrayList<Integer>();
        Collection <?> collection7 = new ArrayList<String>();
        Collection <?> collection8 = new ArrayList<Object>();
    }
}