编译期检查数据类型。
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:
要么指定父类的泛型,要么原封不动的叠加。
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,或者特定类型。
继承关系需要加一些强转: