JavaSE——泛型

152 阅读3分钟

泛型的概念

泛型(Generics)从JDK1.5开始使用,泛型的使用主要目的是可以建立具有类型安全的集合框架,如链表、散列函数等数据结构。

类型安全相关:

  • Java是强类型语言,编译器会对代码进行检查,若是出现赋值、方法调用过程中出现类型不符,编译器就会报错。
  • Java的类型检查基于一个简单的事实:每一个变量的声明都会给出一个类型,每一个方法包括构造方法会给出一个特征。Java编译器会根据这个特征来分辨与决定该声明的明显类型(apparent type),Java编译器即可据此进行类型检查。

Java泛型最重要的一个优点就是:在使用这些泛型类建立的数据结构时,不必进行强制类型转换,即不要求进行运行时的类型检查。JDK1.5编译器在泛型使用时,将运行时的类型检查提前到编译时执行,使代码更安全。总而言之,泛型的推出就是为了建立具有类型安全的数据结构。

泛型类声明

可以使用“class 名称<泛型列表>”声明一个类,为了和普通类有所区别,这样声明的类称作泛型类:

class Bigmac<E>

Bigmac是泛型类的名称,E是其中的泛型,并没有指定E是何种类型的数据,它可以是任何对象或者接口,但不能是基本的数据类型。同时不用字母E也可以,可使用任何一个合法的标识符。泛型声明时,”泛型列表“给出的泛型可以作为类的成员变量的类型、方法的类型以及局部变量的类型。

设计一个锥体,只关心它的底面积是多少,不考虑底的具体形状,只关注底面积和高计算出其体积。因此可以用泛型来作为其底:

class Cone<E>
    double height;
    E bottom;
    public Cone (E b) {
        bottom = b;
    }
}

使用泛型类声明对象

和普通类相比,泛型类声明时会多个<>,而且必须要用具体的类型替换<>中的泛型。

Cone<Circle> coneOne;
coneOne = new Cone<Circle>(new Circle)

下面例子中,声明一个泛型类Cone,只关注其体积,通过传入不同形状的底面类来看泛型的应用是如何的: Cone.java

public class Cone<E>{
    double height;
    E bottom; //用泛型类E声明对象
    public Cone (E b){
        bottom = b;
    }

    public void setheight(double h){
        height = h;
    }

    public double calculate(){
    String s = bottom.toString(); //泛型变量只能调用从Object类继承或重写的方法
    double area = Double.parseDouble(s);
    return 1.0/3.0*area*height;
    }
}

Rect.java

public class Rect{
    double sideA, sideB, area;
    Rect(double a, double b)
        sideA = a;
        sideB = b;
    }
    public String toString(){
        area = sideA*sideB;
        return ""+area;
    }
}

Circle.java

public class Circle{
    double area, radius;
    Circle(double r){
        radius = r;
    }
    public string toString(){
        area = radius * radius * Math.PI;
        return ""+area;
    } 
}

Example.java

public class Example{
    public static void main(String arhs[]){
        Circle circle = new Circle(10);
        Cone<Circle> coneOne = new Cone<Circle>(circle); //创建一个圆锥对象
        coneOne.setheight(16);
        System.out.println(coneOne.calculate());
        Rect rect = new Rect(10,20);
        Cone<Rect> coneTwo = new Cone<Rect>(rect); //创建锥体对象
        coneTwo.setheight(30);
        System.out.println(conTwo.calculate());
    }
}