泛型是一种"代码模板"
T可以是任何class. 编写一次模板, 创建任意类型的ArrayListArrayList<T>, 然后再代码中为用到的类创建ArrayList<类型>ArrayList<T> implements List<T>: ArrayList<T>向上转型为List<T>ArrayList<Integer>和ArrayList<Number>两者完全没有继承关系Object.Object没有发挥泛型的优势.List<Number> list = new ArrayList<>;<T>, 然后在这个类里面就有了这么一种类型T, 任意使用<T>不能用于静态方法public class Pair<T> {
private T first;
private T last;
public Pair(T first, T last) {
this.first = first;
this.last = last;
}
public T getFirst() {
return first;
}
public T getLast() {
return last;
}
// 对于静态方法使用<T>
public static<K> Pair<K> create(K first, K last) {
return new Pair<K>(first, last);
}
}
<T, K>Pair<String, Integer>T视为Object处理.T的类型, 自动为我们实行安全地强制类型.<T>不能是基本类型, 例如int, 因为实际类型是Object.Class: <T>是Object, 无论T的类型是什么, getClass()返回同一个Class实例Class: 不存在Pair<String>.class, 只存在唯一的Pair.classT类型: 只能通过反射传入实现.equals(T t)不会覆写成功, 因为摩擦成equals(Object t), 这就是一个覆写方法了class IntPair extends Pair<Integer> {
public IntPair(Integer first, Integer last) {
super(first, last);
}
}
public class Pair<T> {
private T first;
private T last;
public Pair(T first, T last) {
this.first = first;
this.last = last;
}
}
// 可以直接使用: Integer ip = new IntPair(1, 2)
// 获取继承泛型类型方法
Class<IntPair> clazz = IntPair.class;
Type t = clazz.getGenericSuperclass();
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) t;
Type[] types = pt.getActualTypeArguments();
Type firstType = types[0];
Class<?> typeClass = (Class<?>) firstType;
System.out.println(typeClass);
}
Class来标识泛型不够用. 所以: java类型的体系如下:Pair<Integer>类型, 符合参数Pair<? extends Number>: 上界通配符, 类型T上界限定在NumbersetFirst(? extends Number)无法传递任何Number类型给setFirst(? extends Number)null, // ok, 但是后面排除NullPointerExceptionget获取一个指定类型的返回结果set进行设置和修改类型extends通配符表示可以读, 不能写.Pair<T>的时候, 可以使用extends通配符来限定T的类型set(? super Integer)传入Integer的引用get()方法获得Integer的引用<? super Integer>通配符作为方法参数, 便是方法内部代码对于参数只能写, 不能读extends和super通配符<? extends T>允许调用方法T get()获取T的引用, 但不允许调用方法set(T)传入T的引用(传入null除外)<? super T>允许调用方法set(T)传入T的引用, 但不允许调用方法T get()获取T的引用(获取Object除外)class Collections {
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
// 编辑器可以避免: 意外读取dest, 意外操作src. 安全操作数组
for (int i = 0; i < src.size(); i++) {
T t = src.get(i);
dest.add(t);
}
}
}
T, 它是生产者(Producer), 需要使用extends通配符T, 它是消费者(Consumer), 需要使用super通配符T的src是生产者, 声明为<? extends T>T的dest是消费者, 声明为<? super T>?void sample(Pair<?> p) {}<?>具体作用:
set<T>方法传入引用T(null除外)T get<>方法并获取T引用(只能获取Object引用)null判断null判断, 大多数情况下, 引入泛型参数<T>消除<?>通配符Pair<?>是所有的Pair<T>的超类Pair<Integer> p = new Pair<>(123, 456);
Pair<?> p2 = p; // 安全的向上转型
Class<T>就是泛型Class的getSuperclass()方法返回的Class类型是Class<? super T>Constructor<T>也是泛型Class<Integer> clazz = Integer.class;
Constructor<Integer> cons = clazz.getConstructor(int.class);
Integer i = cons.newInstance(123);
new操作符创建, 必须通过强制转型实现.// Pair<String>[] ps = null; // ok
// Pair<String>[] ps = new Pair<String>[2]; // Cannot create a generic array of Pair<String>
Pair<String>[] ps = (Pair<String> []) new Pair[2];
class ABC<T> {
// T[] createArray() {
// return new T[5];
// }
T[] createArray(Class<T> cls) { // 借助`Class<T>创建泛型数组`
return (T[]) Array.newInstance(cls, 5);
}
}
int和Integer两种类型的关系和区别?原文:https://www.cnblogs.com/zhangrunhao/p/12655285.html