文章目录
核心理念
编译期检查数据类型。
List<String>只能存放String类型的数据。
减少强制类型转换。
List<String>取出来就是String类型。
代码复用。
List<String>和List<Integer>用的是同一套代码。
本质上是一种数据类型,但要到编译期才能知道具体的类型。
小案例
以下代码会正常运行:
@Test
public void f1() {
List<String> list = new ArrayList<>();
list.add("1");
}
以下代码,编译会失败:
@Test
public void f1() {
List<String> list = new ArrayList<>();
list.add(1);
}
显示异常为:
java: 对于add(int), 找不到合适的方法
方法 java.util.Collection.add(java.lang.String)不适用
(参数不匹配; int无法转换为java.lang.String)
方法 java.util.List.add(java.lang.String)不适用
(参数不匹配; int无法转换为java.lang.String)
IDE也会报红:
常用区域
类,接口
class xxx <A,B,C,...>{}
如此,类中可以出现ABC等类型。
public static class A<T> {
public T msg;
public T get(T t) {
T a;
return t;
}
}
写代码时:
T是个Object。
声明时:
指定为String,T就是String。
不指定,就还是Object。
Tips:
- T不能指定为 int 等非Object。
- T类型的成员不能为static。
继承,实现
要么指定父类的泛型,要么原封不动的叠加。
public class A<T> {
}
public class B<M> extends A<String> {
}
指定:B没有限制
public class A<T> {
}
public class B<M, T> extends A<T> {
}
叠加:B必须要有T类型
方法
此泛型一般由参数的泛型决定。
public <E> E get(List<E> e) {
E f = null;
return f;
}
在调用方法的时候才能确定 E 代表的类型。
限定范围
我不是什么都能装的
public class A<T extends Collection> {
private void f1(T t) {
t.add("A");
}
}
此处,指定T的时候,T需要为Collection的子类。
指定为String则会报错。
甚至可以使用Collection的方法。
去除泛型
想把泛型从代码中去掉,简单的方法是替换为Object,或者特定类型。
继承关系需要加一些强转: