Java 泛型
2018-12-29 本文已影响6人
赵哥窟
什么是泛型
泛型实质上就是使用程序员定义安全的数据类型。在没有出现泛型之前,Java也提供了对Object的引用“任意化”操作,这种“任意化”操作就是对Object引用进行向下转型及向上转型操作。但是某些强制类型转换的错误也许不会被编译器捕捉,而在运行后出现异常,可见强制类型换换存在安全隐患,所以在此提供了泛型机制。
回顾向上向下转型
首先看一个例子
public class Test {
private Object b;
public Object getB() {
return b;
}
public void setB(Object b) {
this.b = b;
}
public static void main(String[] args){
Test t = new Test();
t.setB(new Boolean(true)); // 向上转型操作
System.out.println(t.getB());
t.setB(new Float(12.3)); // 向下转型操作
Float f = (float)t.getB();
System.out.println(f);
}
}
这个例子中,向上转型是安全的,向下转型如果操作时用错了类型,就会出现异常。
t.setB(new Float(12.3)); // 向下转型操作
Integer f = (Integer)t.getB();
System.out.println(f);
报错
Exception in thread "main" java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer
而泛型机制有效的解决了这一问题。
泛型
在JDK1.5后提出了泛型机制,语法如下:
类名<T>
上面的例子用泛型实现,代码如下
public class OverClass<T> {
private T over;
public T getOver() {
return over;
}
public void setOver(T over) {
this.over = over;
}
public static void main(String[] args){
OverClass<Boolean> over1 = new OverClass<Boolean>();
OverClass<Float> over2 = new OverClass<Float>();
over1.setOver(true); // 不需要进行类型转换
over2.setOver(12.3f);
Boolean b = over1.getOver(); // 不需要进行类型转换
Float f = over2.getOver();
System.out.println(b);
System.out.println(f);
}
}
可以将OverClass类称为泛型类,同时返回和接受的参数使用T这个类型,最后在主方法中可以使用Over<Boolean>形式返回一个Bollean型对象,使用OverClass<Float>形式返回一个Float型对象,使这两个对象分别调用setOver()方法时,不需要进行向下转型操作,直接将getOver()方法返回的值赋予相应的类型变量即可。
注意:
1、使用泛型这种形式将不会发生ClassCastException异常,因为在编译器中就可以检查类型匹配是否正确。
2、在定义泛型类是,一般类型名称使用T来表达,而容器的元素使用E来表达。
用法
定义泛型类时声明数组类型
public class ArrayClass<T> {
private T[] array;
public void setT(T[] array) {
this.array = array;
}
public T[] getT() {
return array;
}
public static void main(String[] args){
ArrayClass<String> a = new ArrayClass<String>();
String[] array = {"成员1","成员2","成员3","成员4","成员5","成员6"};
a.setT(array);
for (int i = 0; i < a.getT().length; i++) {
System.out.println(a.getT()[i]);
}
}
}
限制泛型可用类型
语法如下:
class 类名称<T extends anyClass>
anyClass指某个接口或类。使用泛型限制后,泛型类型必须实现或继承了anyClass这个接口或类。无论anyClass是接口还是类,在进行泛型限制时都必须使用extends关键字。
public class LimitClass<T extends List> {
public static void main(String[] args){
LimitClass<ArrayList> l1 = new LimitClass<ArrayList>();
LimitClass<LinkedList> l2 = new LimitClass<LinkedList>();
// 这句是错误的,因为HashMap没有实现List()接口
LimitClass<HashMap> l3 = new LimitClass<HashMap>();
}
}
类型通配符
类型通配符:主要作用是在创建一个泛型类型对象时限制这个泛型类的类型实现或继承某个接口或类的子类。要声明这样一个对象可以使用“?”同时使用extends关键字来对泛型加以限制。
泛型类名称<?extends List> a = null;