如果想整体性的学习,可以从上一篇看起
Android工程师必备基础技能(一)注解 - 简书 (jianshu.com)
1.为什么需要泛型?
-
拥有不同参数类型却有相同的执行流程的方法,需要使用泛型;
-
指定数据类型,可以在编译期间发现类型错误,也不需要进行强制类型转换;
1.1.泛型类和泛型方法、泛型接口的定义
泛型类:
public class A<T>{
private T data; public A(T d){
}
public T getData(){
return data;
}
……
}
泛型接口:
public interface impl<T>{public T method();}
//定义1
class impls<T> implements impl<T>{
}
//调用1,也是泛型
class impls implements impl<String>{
public String method();
}
//调用2,指定了具体类型
泛型方法: (完全独立,不一定要声明在泛型类和泛型接口中)
public <T> T method(T,……) {
}
<T>泛型方法的标志
class.<String>method();
//调用1
class.method();
//调用2
1.2.泛型方法辨析
正确判断泛型方法: <T>开头
1.3.限定类型
extends :指定泛型类派生于哪个类/接口
public class <T extends c&i>
public <T,V extends c&i> T method(T a,V b);
类和接口混用,类要放在开头,有且只能有1个类
1.4.泛型中的约束和局限性
-
不能实例化类型变量:
new T()//
不行 -
静态域和静态方法里不能引用类型变量
private statc T instance;//
不行,因为在对象创建的时候,才知道T的具体类型 -
静态方法本身可以是泛型方法
-
泛型只能是类,不能用基础类型,可以用包装类
-
泛型不支持
instanceof
; -
泛型的原生类型,类型不会因为T的改变而改变:
Test<T>
的对象t(String)
和t(Float)
的类型是一样的 -
泛型可以声明数组,却不能
new
:
Test<T>
Test<Float>[] arrays;
//可以
Test<Float>[] arrays = new Test<Float>[10];
//不可以
- 泛型类不能够
extends Exception
和Throwable,try……catch
不能够捕获泛型类对象,但可以捕获Throwable
。
public <T extends Throwable> void doWork(T x) {
try{}catch(T x){
}
//不行
try{} catch(Throwable e) throw T{throw t;}
//可以
}
1.5.泛型类型的继承规则
-
class A extends B;C<T> C<A>和C<B>没有任何关系,类型之间有继承关系不代表泛型之间有继承关系
-
泛型类可继承自泛型类 class A<T> extends B<T> A<Strnig> a = new B<String>//可以
1.6.通配符类型
解决继承规则中C<A>和C<B>没有任何关系的局限。
class<T> A;
method(A<? extends/super B>)
? extends B:主要用于安全的访问数据,访问类型B
限定了泛型类型的上限;必须派生B的派生类;调用时增加
get一定是B;set不能用。
限定了泛型类型的下限;必须是B的超类;
设置只能设置本身和子类,返回只能返回Object,主要用于安全的写入数据.
1.7.虚拟机如何实现泛型
类型擦除 T 擦除成Object,T extends A,擦除成A(第一个)。实现接口时,在适当的位置加强制类型转化
重载时,泛型参数的类型不通过。
下一篇:Android工程师必备基础技能(三)Retrofit中的注解原理项目实践
网友评论