1.泛型
泛型类、泛型接口、泛型方法、Class<T>类传递及泛型数组
2.泛型作用在编译阶段
假如不使用泛型,使用Object,需要强制转换,且在编译阶段检测不出来;固后来有了泛型,在编译阶段进行检测。
3.各种泛型定义和使用方法
3.1 泛型类
//定义
class Point<T>{// 此处可以随便写标识符号
private T x ;
private T y ;
public void setX(T x){//作为参数
this.x = x ;
}
public void setY(T y){
this.y = y ;
}
public T getX(){//作为返回值
return this.x ;
}
public T getY(){
return this.y ;
}
};
//IntegerPoint使用
Point<Integer> p = new Point<Integer>() ;
p.setX(new Integer(100)) ;
System.out.println(p.getX());
//FloatPoint使用
Point<Float> p = new Point<Float>() ;
p.setX(new Float(100.12f)) ;
System.out.println(p.getX());
3.2 泛型接口
interface Info<T>{ // 在接口上定义泛型
public T getVar() ; // 定义抽象方法,抽象方法的返回值就是泛型类型
public void setVar(T var);
}
class InfoImpl<T> implements Info<T>{ // 定义泛型接口的子类
private T var ; // 定义属性
public InfoImpl(T var){ // 通过构造方法设置属性内容
this.setVar(var) ;
}
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
}
public class GenericsDemo24{
public static void main(String arsg[]){
InfoImpl<String> i = new InfoImpl<String>("harvic");
System.out.println(i.getVar()) ;
}
};
3.3 泛型方法
3.3.1 没有返回值的泛型方法
public class StaticFans {
//静态函数
public static <T> void StaticMethod(T a){
Log.d("harvic","StaticMethod: "+a.toString());
}
//普通函数
public <T> void OtherMethod(T a){
Log.d("harvic","OtherMethod: "+a.toString());
}
}
使用方法:
//静态方法
StaticFans.StaticMethod("adfdsa");//使用方法一
StaticFans.<String>StaticMethod("adfdsa");//使用方法二
//常规方法
StaticFans staticFans = new StaticFans();
staticFans.OtherMethod(new Integer(123));//使用方法一
staticFans.<Integer>OtherMethod(new Integer(123));//使用方法二
3.3.2 有返回值的泛型方法
public static <T> List<T> parseArray(String response,Class<T> object){
List<T> modelList = JSON.parseArray(response, object);
return modelList;
}
3.3.3返回值为数组
在写程序时,大家可能会遇到类似String[] list = new String[8];的需求,这里可以定义String数组,当然我们也可以定义泛型数组,泛型数组的定义方法为 T[],与String[]是一致的,下面看看用法:
//定义 public static <T> T[] fun1(T...arg){ // 接收可变参数 return arg ; // 返回泛型数组 } //使用 public static void main(String args[]){ Integer i[] = fun1(1,2,3,4,5,6) ; Integer[] result = fun1(i) ; }
3.4
使用Class<T>传递泛型类Class对象
有时,我们会遇到一个情况,比如,我们在使用JSON解析字符串的时候,代码一般是这样的
public static List<SuccessModel> parseArray(String response){
List<SuccessModel> modelList = JSON.parseArray(response, SuccessModel.class);
return modelList;
}
其中SuccessModel是自定义的解析类,代码如下,其实大家不用管SuccessModel的定义,只考虑上面的那段代码就行了。写出来SuccessModel的代码,只是不想大家感到迷惑,其实,这里只是fastJson的基本用法而已。
这段代码的意义就是根据SuccessModel解析出List<SuccessModel>的数组。
public class SuccessModel {
private boolean success;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
}
首先,我们应该把SuccessModel单独抽出来做为泛型变量,但parseArray()中用到的SuccessModel.class要怎么弄呢?
先来看代码:
public static <T> List<T> parseArray(String response,Class<T> object){
List<T> modelList = JSON.parseArray(response, object);
return modelList;
}
注意到,我们用的Class<T> object来传递类的class对象,即我们上面提到的SuccessModel.class。
这是因为Class<T>也是一泛型,它是传来用来装载类的class对象的,它的定义如下:
public final class Class<T> implements Serializable {
…………
}
4. 泛型默认类型,类型绑定
泛型默认继承Object,故泛型对象默认只能使用Object的方法。
有时候,你会希望泛型类型只能是某一部分类型,比如操作数据的时候,你会希望是Number或其子类类型。这个想法其实就是给泛型参数添加一个界限。其定义形式为:
class Fruit {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static <T extends Fruit> String getFruitName(T t){
return t.getName();
}
class Banana extends Fruit{
public Banana(){
setName("bababa");
}
}
class Apple extends Fruit{
public Apple(){
setName("apple");
}
}
String name_1 = getFruitName(new Banana());
String name_2 = getFruitName(new Apple());
Log.d(TAG,name_1);
Log.d(TAG,name_2);
输出结果
bababa
apple
绑定多个限定
上面我们讲了,有关绑定限定的用法,其实我们可以同时绑定多个绑定,用&连接,比如:
public static <T extends Comparable & Serializable, U extends Runnable> T foo(T a, U b){
…………
}
5.通配符?
<? extends XXX>指填充为派生于XXX的任意子类的话,那么<? super XXX>则表示填充为任意XXX的父类!
?extends父类,?代表子类,故能取不能存;?super 子类,?代表子类,能存,不能取。
构造泛型实例时,如果省略了填充类型,则默认填充为无边界通配符!
?是通配符,泛指所有类型
一般用于定义一个引用变量,这么做的好处是,如下所示,定义一个sup的引用变量,就可以指向多个对象。
SuperClass<?> sup = new SuperClass<String>(“lisi”);
sup = new SuperClass<People>(new People());
sup = new SuperClass<Animal>(new Animal());
若不用?,用固定的类型的话,则:
SuperClass<String> sup1 = new SuperClass<String>(“lisi”);
SuperClass<People> sup2 = new SuperClass<People>(“lisi”);
SuperClass<Animal> sup3 = new SuperClass<Animal>(“lisi”);
这就是?通配符的好处。
参考:
https://qijian.blog.csdn.net/article/details/49883589