看下面这段代码:
(资料图片)
private static int add(int a, int b) {    System.out.println(a + "+" + b + "=" + (a + b));    return a + b;}private static float add(float a, float b) {    System.out.println(a + "+" + b + "=" + (a + b));    return a + b;}private static double add(double a, double b) {    System.out.println(a + "+" + b + "=" + (a + b));    return a + b;}如果没有泛型,要实现不同类型的加法,每种类型都需要重载一个add方法;通过泛型,我们可以复用为一个方法:
private static  double add(T a, T b) {    System.out.println(a + "+" + b + "=" + (a.doubleValue() + b.doubleValue()));    return a.doubleValue() + b.doubleValue();} 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
下面这段代码:
List list = new ArrayList();list.add("xxString");list.add(100d);list.add(new Person());我们在使用上述list中,list中的元素都是Object类型(无法约束其中的类型),所以在取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出java.lang.ClassCastException`异常。
引入泛型,它将提供类型的约束,提供编译前的检查:
List list = new ArrayList();// list中只能放String, 不能放其它类型的元素  泛型的好处1、编译时,检查添加元素的类型,提高了安全性
2、减少了类型转换的次数,提高效率
3、不再提示编译警告
介绍1.泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题
2.在类声明或实例化时只要指定好需要的具体的类型即可。
3.Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException.异常。同时,代码更加简洁、健壮
4.泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型。
代码举例:
public class Generic03 {    public static void main(String[] args) {        //注意,特别强调:E具体的数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型        Person person = new Person<>("dfdfs");        person.show();//String        /**         * Person类相当于下面这样子         * class Person{         *     String s;//E表示s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型         *         *     public Person(String s) {//E也可以是参数类型         *         this.s = s;         *     }         *         *     public String f(){//返回类型使用E         *         return s;         *     }         *     public void show(){         *         System.out.println(s.getClass());//显示s的运行类型         *     }         * }         */        Person person2 = new Person<>(100);        person2.show();        /**         * Person类相当于下面这样子         * class Person{         *     Integer s;//E表示s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型         *         *     public Person(Integer s) {//E也可以是参数类型         *         this.s = s;         *     }         *         *     public Integer f(){//返回类型使用E         *         return s;         *     }         *     public void show(){         *         System.out.println(s.getClass());//显示s的运行类型         *     }         * }         */    }}//泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型class Person{    E s;//E表示s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型    public Person(E s) {//E也可以是参数类型        this.s = s;    }    public E f(){//返回类型使用E        return s;    }    public void show(){        System.out.println(s.getClass());//显示s的运行类型    }}   语法泛型的声明interface 接口名
说明:
1)其中,T,K,V不代表值,而是表示类型
2)任意字母都可以。常用T表示,是Type的缩写
泛型的实例化要在类名后面指定类型参数的值(类型)。如:
List strList = new ArrayList();Iterator iterator = customers.iterator();   泛型使用举例需求:
1.创建3个学生对象
2.放入到HashSet中学生对象,使用.
3.放入到HashMap中,要求Key 是String name,Value就是学生对象
4.使用两种方式遍历
public class GenericExercise {    public static void main(String[] args) {        //使用泛型方式给HashSet放入3个学生对象        HashSet students = new HashSet<>();        students.add(new Student("jack",18));        students.add(new Student("tom",18));        students.add(new Student("ml",18));        //第一种遍历方式,增强for循环        for (Student student:students){            System.out.println(student);        }        //使用泛型方式给HashMap放入3个学生对象        HashMap hm = new HashMap<>();        hm.put("milan",new Student("milan",34));        hm.put("jack",new Student("jack",31));        hm.put("tom",new Student("tom",30));        //2.迭代器        Set> entries = hm.entrySet();        Iterator> iterator = entries.iterator();        System.out.println("==========================");        while (iterator.hasNext()){            Map.Entry next = iterator.next();            System.out.println(next.getKey()+"-"+next.getValue());        }    }}class Student{    private String name;    private int age;    public Student(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Override    public String toString() {        return "Student{" +                "name="" + name + "\"" +                ", age=" + age +                "}";    }}     泛型使用注意事项1.interface 接口名
List list = new ArrayList();//这样写正确List list = new ArrayList();//这样写错误    2.在给泛型指定具体类型后,可以传入该类型或者其子类类型
3.泛型使用形式
//1.第一种方式List list1 = new ArrayList();//2.第二种方式List Iist2 = new ArrayList<>();   3.如果我们这样写List list3=new ArrayList();默认给它的泛型是 E就是Object.,等价于ArrayList

