一、泛型的定义和使用
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 ;
}
};
//Integer
Point<Integer> p = new Point<Integer>() ;
p.setX(new Integer(100)) ;
System.out.println(p.getX());
//Float
Point<Float> p = new Point<Float>() ;
p.setX(new Float(100.12f)) ;
System.out.println(p.getX());
以point为例,
(1)定义泛型:Point<T>
Point<T>,即在类名后面加一个尖括号,括号里是一个大写字母。这里的T可以是任何大写字母,意义是相同的,但是为了提高可读性,一般约定俗成的字母意义为:
- E — Element,常用在java Collection里,如:List<E>,Iterator<E>,Set<E>
- K,V — Key,Value,代表Map的键值对
- N — Number,数字
- T — Type,类型,如String,Integer等等
(2)类中使用泛型
这个T表示派生自Object类的任何类,比如String,Integer,Double等等。
//定义变量
private T x ;
//作为返回值
public T getX(){
return x ;
}
//作为参数
public void setX(T x){
this.x = x ;
}
(3)使用泛型类
//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.34f)) ;
System.out.println(p.getX());
我们构造时为class Point<T>,所以在使用的时候也要在Point后加上类型来定义T代表的意义。
(4)使用泛型实现的优势
a. 不用强制转换
//使用Object作为返回值,要强制转换成指定类型
Float floatX = (Float)floatPoint.getX();
//使用泛型时,不用强制转换,直接出来就是String
System.out.println(p.getVar());
b.在settVar()时如果传入类型不对,编译时会报错
当我们构造时使用的是String,而在setVar时,传进去Integer类型时,就会报错。而不是像Object实现方式一样,在运行时才会报强制转换错误
二、多泛型
定义和使用
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());
三、泛型接口定义及使用
(1)非泛型类和泛型类的定义和使用
interface Info<T>{ // 在接口上定义泛型
public T getVar() ; // 定义抽象方法,抽象方法的返回值就是泛型类型
public void setVar(T x);
}
//使用:非泛型类
//InfoImpl不是一个泛型类,因为类名后没有<T>!,所以需要implements Info<String>,显式指定T的类型为String
class InfoImpl implements Info<String>{ // 定义泛型接口的子类
private String var ; // 定义属性
public InfoImpl(String var){ // 通过构造方法设置属性内容
this.setVar(var) ;
}
@Override
public void setVar(String var){
this.var = var ;
}
@Override
public String getVar(){
return this.var ;
}
}
public class GenericsDemo24{
public void main(String arsg[]){
InfoImpl i = new InfoImpl("harvic");
System.out.println(i.getVar()) ;
}
};
//泛型类
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)泛型变量的类
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 Fans {
//静态函数
public static <T> void StaticMethod(T a){
log.info("StaticMethod: "+a.toString());
}
//普通函数
public <T> void OtherMethod(T a){
log.info("OtherMethod: "+a.toString());
}
}
//静态方法
Fans .StaticMethod("adfdsa");//使用方法一
Fans .<String>StaticMethod("adfdsa");//使用方法二
//常规方法
Fans staticFans = new StaticFans();
Fans .OtherMethod(new Integer(123));//使用方法一
Fans .<Integer>OtherMethod(new Integer(123));//使用方法二
//返回值中存在泛型
public static <T> List<T> parseArray(String response,Class<T> object){
List<T> modelList = JSON.parseArray(response, object);
return modelList;
}
五、其它用法:Class<T>类传递及泛型数组
(1)Class<T>
public static List<SuccessModel> parseArray(String response){
List<SuccessModel> modelList = JSON.parseArray(response, SuccessModel.class);
return modelList;
}
//变成泛型
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 {
…………
}
(2)泛型数组
//定义
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) ;
}
定义了一个静态函数,然后定义返回值为T[],参数为接收的T类型的可变长参数。