泛型的解释
泛型: 泛型属于一种程序设计语言的的标准和规范,或者也可以说为特性。
通俗的解释泛型: 泛型其实就是我们参数化类型,就比如在定义List的时候,我们就可以写作List<String>
这样我们就在编码阶段,将List存放的类型定义好。这样的话,我们在操作List的时候就可以通过泛型对我们集合内的值进行规范和约束,如果我们传入非法的类型时程序在编译阶段就能帮我们找出问题,就不会出现隐形的异常。
如下例子中,如果我们不通过泛型进行约束,写代码,运行代码的时候我们都是不知道会出错,只有当程序执行到这句话的时候才会抛出异常。
List list = new ArrayList();
list.add("abc");
list.add(100);
for(int i = 0; i< list.size();i++){
System.out.println("执行到第 " + (i+1) + " 次循环。");
String str = (String) list.get(i);
System.out.println(str);
}
执行结果:
执行到第 1 次循环。
abc
执行到第 2 次循环。
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at com.zhj.business.test.Test01.main(Test01.java:18)
结果分析:可以看出程序完整的完成了第一次循环,是在第二次循环时才触发类型转换异常的。当项目很大的时候,像这样的细节是很容易被忽略的,所以我们通过泛型,约束类型,这样我们在提取数据保存是对应类型即可,不需要进行强转,就不会出现上诉问题。
泛型的特性
在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。
泛型信息是不会进入到运行时阶段。
总结: 泛型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。
泛型的用法
泛型共有三种使用方式,分别为:
泛型类
public class Result<T> implements Serializable { /** * 状态码 */ private Integer code; /** * 消息 */ private String msg; /** * 返回数据 */ private T data; public Result(Integer code, String msg, T data) { this.code = code; this.msg = msg; this.data = data; } }
泛型接口
List其实就是最典型的泛型接口
public interface List<E> extends Collection<E> { }
泛型方法
List 接口中的toArray()方法就是典型的泛型方法
/** * 泛型方法的基本介绍 * @param T[] 传入的泛型实参 * @return T[] 返回值为T[]类型 * 说明: * 1)public与返回值中间的<T>,可以理解为声明此方法为泛型方法。 * 2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。 * 3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。 * 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。 * 5)必须在权限声明public与返回值之间的<T>上添加上下边界,即在泛型声明的时候添加 */ public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size,(Class<? extends T[]>) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }
注意:
- 泛型的类型参数只能是类类型,不能是简单类型。
- 不能对确切的泛型类型使用instanceof操作。
- 实现泛型接口时,未传入泛型实参时,在声明类的时候,需将泛型的声明也一起加到类中,List必须指定,不然会报错,如下示例
public interface List extends Collection
- 如果静态方法要使用泛型的话,无法访问泛型类型的参数,必须将静态方法也定义成泛型方法
public static void show(T t)
- 泛型可以指定边界
<T extends Number>
泛型方法上指边界必须在权限声明与返回值之间的上添加 - 泛型方法中权限声明与返回值之间的 ,还可以指定多个泛型<T,K>
- 类型通配符一般是使用?代替具体的类型实参List<?> 通配符>代替的是String之类的实参。
泛型的灵活应用能够极大的加强程序的质量,大家可以积极的应用。