转Java泛型详解:
//泛型类的定义
class Point{// 此处可以随便写标识符号
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 p = new Point() ;
p.setX(new Integer(100)) ;
System.out.println(p.getX());
//FloatPoint使用
Point p = new Point() ;
p.setX(new Float(100.12f)) ;
System.out.println(p.getX());
class MorePoint {
private T x;
private T y;
private U name;
public void setX(T x) {
this.x = x;
}
public T getX() {
return this.x;
}
…………
public void setName(U name){
this.name = name;
}
public U getName() {
return this.name;
}
}
//使用
MorePoint morePoint = new MorePoint();
morePoint.setName("harvic");
Log.d(TAG, "morPont.getName:" + morePoint.getName());
//也就是在原来的T后面用逗号隔开,写上其它的任意大写字母即可。想加几个就加几个,比如我们想加五个泛型变量,那应该是这样的:
//字母规范:在定义泛型类时,我们已经提到用于指定泛型的变量是一个大写字母:
class MorePoint{
}
//定义泛型接口
interface Info{ // 在接口上定义泛型
public T getVar() ; // 定义抽象方法,抽象方法的返回值就是泛型类型
public void setVar(T var);
}
//实现接口
class InfoImpl implements Info{ // 定义泛型接口的子类
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 i = new InfoImpl("harvic");
System.out.println(i.getVar()) ;
}
};
class InfoImpl implements Info{ // 定义泛型接口的子类
private U var ;
private T x;
private K y;
public InfoImpl(U var){ // 通过构造方法设置属性内容
this.setVar(var) ;
}
public void setVar(U var){
this.var = var ;
}
public U getVar(){
return this.var ;
}
}
//使用
public class GenericsDemo24{
public void main(String arsg[]){
InfoImpl i = new InfoImpl("harvic");
System.out.println(i.getVar()) ;
}
}
public class StaticFans {
//静态函数
public static void StaticMethod(T a){
Log.d("harvic","StaticMethod: "+a.toString());
}
//普通函数
public void OtherMethod(T a){
Log.d("harvic","OtherMethod: "+a.toString());
}
}
//使用
//静态方法
StaticFans.StaticMethod("adfdsa");//使用方法一
StaticFans.StaticMethod("adfdsa");//使用方法二
//常规方法
StaticFans staticFans = new StaticFans();
staticFans.OtherMethod(new Integer(123));//使用方法一
staticFans.OtherMethod(new Integer(123));//使用方法二
/*
从结果中我们可以看到,这两种方法的结果是完全一样的,但他们还有些区别的,区别如下:
方法一,可以像普通方法一样,直接传值,任何值都可以(但必须是派生自Object类的类型,比如String,Integer等),函数会在内部根据传进去的参数来识别当前T的类别。但尽量不要使用这种隐式的传递方式,代码不利于阅读和维护。因为从外观根本看不出来你调用的是一个泛型函数。
方法二,与方法一不同的地方在于,在调用方法前加了一个来指定传给的值,如果加了这个来指定参数的值的话,那StaticMethod()函数里所有用到的T类型也就是强制指定了是String类型。这是我们建议使用的方式。
同样,常规泛型函数的使用也有这两种方式:
*/
StaticFans staticFans = new StaticFans();
staticFans.OtherMethod(new Integer(123));//使用方法一
staticFans.OtherMethod(new Integer(123));//使用方法二
可以看到,与平常一样,先创建类的实例,然后调用泛型函数。
方法一,隐式传递了T的类型,与上面一样,不建议这么做。
方法二,显示将T赋值为Integer类型,这样OtherMethod(T a)传递过来的参数如果不是Integer那么编译器就会报错。
上面我们的函数中,返回值都是void,但现实中不可能都是void,有时,我们需要将泛型变量返回,比如下面这个函数:
public static List parseArray(String response,Class object){
List modelList = JSON.parseArray(response, object);
return modelList;
}
函数返回值是List类型。至于传入参数Class object的意义,我们下面会讲。这里也就是想通过这个例子来告诉大家,泛型变量其实跟String,Integer,Double等等的类的使用上没有任何区别,T只是一个符号,可以代表String,Integer,Double……这些类的符号,在泛型函数使用时,直接把T看到String,Integer,Double……中的任一个来写代码就可以了。唯一不同的是,要在函数定义的中在返回值前加上标识泛型;
//定义
public static T toBean(String jsonString, Class beanClass) {
return toBean(parseObj(jsonString), beanClass);
}
//使用
Object转String类型
JSONUtil.toBean(o,new String());
---------------------------------------------------
进阶-如:传什么进去返回什么类型:定义泛型数组:
在写程序时,大家可能会遇到类似String[] list = new String[8];的需求,这里可以定义String数组,当然我们也可以定义泛型数组,泛型数组的定义方法为 T[],与String[]是一致的,下面看看用法:
//定义
public static 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) ;
}