一、啥是泛型
概述
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数。
格式
类名<类型名>
标记符
- E - Element (在集合中使用,因为集合中存放的是元素)
- T - Type(Java 类)
- K - Key(键)
- V - Value(值)
- N - Number(数值)
- ? - 表示不确定的java类型(通配符)
- S、U、V、 - 用在第2、3、4个参数类型时使用
二、代码走一波
汽车类
/** * 汽车类 */ @Data public class Car { /*无参构造*/ public Car() { } /*带参构造*/ public Car(int id, String name, String Type) { this.id = id; this.name = name; this.Type = Type; } /*属性*/ private int id;//编号 private String name;//名称 private String Type;//类型 }
猫猫类
/** * 宠物类 */ @Data public class Pet { /*无参构造*/ public Pet() { } /*带参构造*/ public Pet(int id, String name, String Type) { this.id = id; this.name = name; this.Type = Type; } /*属性*/ private int id;//编号 private String name;//名称 private String Type;//类型 }
泛型类
/** * 泛型测试类 * * @param <T> 参数1(泛型对象) * @param <S> 参数2(继承Pet类的泛型对象) */ @Data public class User<T, S extends Pet> { /*带参构造*/ public User(int id, String name, String Type, List<T> t, List<S> s) { this.id = id; this.name = name; this.Type = Type; this.tList = t; this.sList = s; } /*泛型属性*/ private List<T> tList;//泛型List private List<S> sList;//继承Pet类的泛型List /*一般属性*/ private int id;//编号 private String name;//名称 private String Type;//类型 /*重写toString()方法*/ @Override public String toString() { String msg = "id为【%s】的【%s】用户【%s】拥有猫猫【%s】和汽车【%s】"; return String.format(msg, this.id, this.Type, this.name, this.sList.toString(), this.tList.toString()); } }
测试类
/** * 测试类 */ public class Test { public static void main(String args[]) { List<Pet> petList = new ArrayList<Pet>(); petList.add(new Pet(1, "汤圆", "英短")); petList.add(new Pet(2, "糯米", "英短")); petList.add(new Pet(3, "咖喱", "田园")); List<Car> carList = new ArrayList<Car>(); carList.add(new Car(1, "标志", "小轿车")); carList.add(new Car(2, "哈弗", "SUV")); User user = new User(1, "ZH", "男性", carList, petList);//第5个参数如果不是一个继承了Pet类的List,则编译会报错 System.out.println(user.toString()); } }
输出
小结
我们知道Object类是所有类的父类,在引入泛型概念之前,我们常用Object的引用来实现参数的“任意化”。
痛点:
- 要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。
- 对于强制类型转换错误的情况 ,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处:
- 通过IDE进行代码类型初步检查,然后在编译阶段进行编译类型检查,避免运行时异常,以保证类型转换的安全性。
- 所有的强制转换都是自动和隐式的,可以提高代码的重用率。