泛型通俗总结

一、泛型:类名,参数化。

二、有时在编程时(定义类、定义接口、定义方法时),对于要使用的对象,暂不知道其具体是什么类型,可用“自定义的标识符”(占位符)来代替,我们称之为类型参数。

三、 定义泛型类:

class Point<T1, T2>{   //在定类时,在类名后面,给出“类型参数”T1,T2.在下面的定义体中,就可以使用T1,T2作为“类型名”的替代符了(占位符)
    T1 x;
    T2 y;
    public T1 getX() {
        return x;
    }
    public void setX(T1 x) {
        this.x = x;
    }
    public T2 getY() {
        return y;
    }
    public void setY(T2 y) {
        this.y = y;
    }
}

使用上述定义的泛型类:
Point<Integer, Integer> p1 = new Point<Integer, Integer>();// 实例化泛型类。泛型类在实例化时必须指出具体的类型,也就是向类型参数传值
(1)在 <T1, T2>,T1, T2 是自定义的标识符,称之为类型参数。T1, T2 只是数据类型的占位符,运行时会被替换为真正的数据类型。
(2)类型参数必须是一个合法的标识符,习惯上使用单个大写字母,通常情况下,K 表示键,V 表示值,E 表示异常或错误,T 表示一般意义上的数据类型。
(3)类型参数,在定义类时,需要在所定义的类名后面给出。一旦给出了类型参数,在类的定义体中,就可以使用它了,如
(4)传值参数(我们通常所说的参数)由小括号包围,如 (int x, double y),类型参数(泛型参数)由尖括号包围,多个参数由逗号分隔,如<T> 或 <T, E>
(5)泛型类在实例化时必须指出具体的类型,也就是向类型参数传值,格式为: 
className variable<dataType1, dataType2> = new className<dataType1, dataType2>(); //实例化泛型类(即调用)
除了定义泛型类,还可以定义泛型方法,例如,定义一个打印坐标的泛型方法:

四、 定义泛型方法
public static <V1, V2> void printPoint(V1 x, V2 y){  //类型参数<V1,V2>需要放在修饰符后面、方法(名)回值类型前面
V1 m = x; V2 n = y; System.out.println("This point is:" + m + ", " + n); }
泛型方法的使用:
Point<Integer, Integer> p1 = new Point<Integer, Integer>();//先实例化泛型类,取得其引用
p1.printPoint(p1.getX(), p1.getY());//用类的引用,调用方法

(1)与使用泛型类不同,使用泛型方法时不必用<V1,V2>指明参数类型,编译器会根据传递的参数自动查找出具体的类型。
(2)泛型方法与泛型类没有必然的联系,泛型方法有自己的类型参数,在普通类中也可以定义泛型方法。
泛型方法 printPoint() 中的类型参数 V1,V2 与泛型类 Point 中的 T1, T2 没有必然的联系

五、泛型接口

在Java中也可以定义泛型接口,这里不再赘述,仅仅给出示例代码:

//定义泛型接口
interface Info<T> {
public T getVar();
}

//实现接口
class InfoImp<T> implements Info<T> {        //<  >号,接口名,后面
private T var;


public InfoImp(T var) {                               // 定义泛型构造方法
this.setVar(var);
}

public void setVar(T var) {
this.var = var;
}

public T getVar() {
return this.var;
}
}

六、类型擦除

如果在使用泛型时没有指明数据类型,那么就会擦除泛型类型。如:

定义了型类:

class Point<T1, T2>{
  public T1 getX() {
        return x;
    }

......
}

使用此类时,没有用<>指定具体类型:
  Point p = new Point();  // 类型擦除
int x = (Integer)p.getX(); // 向下转型
因为在使用泛型时没有指明数据类型,为了不出现错误,编译器会将所有数据向上转型为 Object,所以在取出坐标使用时要向下转型

七、限制泛型的可用类型:

对于泛形参数<T1,T2>,不想其可选任意类型,而只想其选某几个类型,如,让它只能接受 Number 及其子类(Integer、Double、Character 等)

则可用 "参数T是某类的子类 " 的方法:

public <T extends Number> T getMax(T array[]){
    T max = null;
    for(T element : array){
        max = element.doubleValue() > max.doubleValue() ? element : max;
    }
    return max;
}

(1)<T extends Number> 表示 T 只接受 Number 及其子类,传入其他类型的数据会报错。这里的限定使用关键字 extends,后面可以是类也可以是接口。
但这里的 extends 已经不是继承的含义了,应该理解为 T 是继承自 Number 类的类型,或者 T 是实现了 XX 接口的类型。

八、注意:一般的应用开发中泛型使用较少,多用在框架或者库的设计中

总结自:https://www.cnblogs.com/cat520/p/9353291.html

猜你喜欢

转载自www.cnblogs.com/godzoo/p/9785642.html
今日推荐