泛型的好处:

1、编译时,检查添加元素的类型,提高了安全性

2、减少了类型转换的次数,提高效率

概念:

1、泛型又称参数化类型,解决数据类型的安全性问题

2、在类声明或实例化时只要指定好需要的具体类型即可

3、java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。会使代码更简洁更健壮

4、泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型

注意事项:

1、E只能是引用类型,不可以是基本数据类型

ArrayList<Integer> integers = new ArrayList<>();//true
ArrayList<int> ints = new ArrayList<int>();//错误

2、在指定泛型具体类型后,可以传入该类型或者其子类类型

public class Study {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        ArrayList<A> as = new ArrayList<>();
        as.add(new B());
    }
}
class A{}
class B extends A{}

3、如果不指定泛型类型,则默认为Object

       ArrayList<Object> arrayList = new ArrayList<>();

自定义泛型类:

class 类名<T,R...>{       成员        }可以有多个泛型

注意事项:

1、普通成员可以使用泛型

2、使用泛型的数组,不能初始化

3、静态方法中不能使用类的泛型

4、泛型类的类型,是在创建对象时确定的(需要指定确定的类型)

5、如果在创建对象时,没有指定类型,默认为Object

class Person<T,E,M>{//Person就称为自定义泛型类
    //普通成员可以使用泛型(属性、方法)
    T name;
    E age;
    M sal;
    T[] ts=new T[3];//使用泛型的数组,不能初始化(不确定T的类型,就无法在开辟空间)
    public Person(T name, E age, M sal) {
        this.name = name;
        this.age = age;
        this.sal = sal;
    }
    public static say(T name){//静态方法不允许使用泛型
        System.out.println(name);
    }
}

自定义泛型接口:

interface  接口名<T,R...>{        }

注意事项:

1、接口中,静态成员也不能使用泛型

2、泛型接口的类型,在继承接口或者实现接口时确定

3、没有指定类型,默认为Object

interface Usb<U,R>{
    R get(U u);
    void say(U u,R r);
}
class A implements Usb<String,Double>{
    @Override
    public Double get(String s) {
        return 1.0;
    }
    @Override
    public void say(String s, Double aDouble) {
        System.out.println(s+aDouble);
    }
}

自定义泛型方法:

修饰符  <T,R...> 返回类型 方法名(参数列表){}

注意事项:

1、泛型方法,可以定义在普通类中,也可以定义在泛型类中

2、当泛型方法被调用时,类型会确定

3、public void say(E e){}修饰符后没有<T,R..>,此时不是泛型方法,而是使用了泛型

class A{
    public <T,R> void say(T t,R r){}//泛型方法
}