java泛型定义及使用

Java泛型详解:<T>和Class<T>的使用 - liftsail - 博客园

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());    

1.1多泛型变量定义

class MorePoint<T,U> {  
    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<Integer,String> morePoint = new MorePoint<Integer, String>();  
morePoint.setName("harvic");  
Log.d(TAG, "morPont.getName:" + morePoint.getName()); 

//也就是在原来的T后面用逗号隔开,写上其它的任意大写字母即可。想加几个就加几个,比如我们想加五个泛型变量,那应该是这样的:
//字母规范:在定义泛型类时,我们已经提到用于指定泛型的变量是一个大写字母:

class MorePoint<T,U,A,B,C>{  
}  

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()) ;  
    }  
};  

2.1多变量泛型接口

class InfoImpl<T,K,U> implements Info<U>{   // 定义泛型接口的子类  
     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<Integer,Double,String> i = new InfoImpl<Integer,Double,String>("harvic");  
        System.out.println(i.getVar()) ;  
    }  
}  

3.泛型函数定义及使用

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));//使用方法二 
/*
从结果中我们可以看到,这两种方法的结果是完全一样的,但他们还有些区别的,区别如下:

方法一,可以像普通方法一样,直接传值,任何值都可以(但必须是派生自Object类的类型,比如String,Integer等),函数会在内部根据传进去的参数来识别当前T的类别。但尽量不要使用这种隐式的传递方式,代码不利于阅读和维护。因为从外观根本看不出来你调用的是一个泛型函数。

方法二,与方法一不同的地方在于,在调用方法前加了一个<String>来指定传给<T>的值,如果加了这个<String>来指定参数的值的话,那StaticMethod()函数里所有用到的T类型也就是强制指定了是String类型。这是我们建议使用的方式。

同样,常规泛型函数的使用也有这两种方式:
*/
StaticFans staticFans = new StaticFans();  
staticFans.OtherMethod(new Integer(123));//使用方法一  
staticFans.<Integer>OtherMethod(new Integer(123));//使用方法二  
可以看到,与平常一样,先创建类的实例,然后调用泛型函数。
方法一,隐式传递了T的类型,与上面一样,不建议这么做。
方法二,显示将T赋值为Integer类型,这样OtherMethod(T a)传递过来的参数如果不是Integer那么编译器就会报错。

3.1泛型函数定义进阶:返回值中存在泛型

上面我们的函数中,返回值都是void,但现实中不可能都是void,有时,我们需要将泛型变量返回,比如下面这个函数:

public static <T> List<T> parseArray(String response,Class<T> object){  
    List<T> modelList = JSON.parseArray(response, object);  
    return modelList;  
}  

函数返回值是List<T>类型。至于传入参数Class<T> object的意义,我们下面会讲。这里也就是想通过这个例子来告诉大家,泛型变量其实跟String,Integer,Double等等的类的使用上没有任何区别,T只是一个符号,可以代表String,Integer,Double……这些类的符号,在泛型函数使用时,直接把T看到String,Integer,Double……中的任一个来写代码就可以了。唯一不同的是,要在函数定义的中在返回值前加上<T>标识泛型;

4.其它用法:Class<T>类传递及泛型数组

//定义 
public static <T> T toBean(String jsonString, Class<T> beanClass) {
        return toBean(parseObj(jsonString), beanClass);
 }
//使用
Object转String类型
JSONUtil.toBean(o,new String());
---------------------------------------------------
进阶-如:传什么进去返回什么类型:定义泛型数组:
在写程序时,大家可能会遇到类似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) ;  
}    

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值