java基础特性:泛型
介绍
Java 泛型(generics)是 JDK1.5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型,在此之前java都是使用object来进行完成这种功能,但是object的向下转型会带来一些类型转化的问题,所以才加入了泛型。
讲解
一、泛型的引入
在jdk1.5以前想要实现类似于C++模板的功能时,一般都是使用object实现,如:实现一个point类,里面有x、y两个数据成员,但是对于x、y类似是不确定的,有时候需要int型的x、y,有时候需要float型的x、y。其实现如下所示:
class Point{
private Object x;
private Object y;
public void setX(Object x) {
this.x = x;
}
public void setY(Object y) {
this.y = y;
}
public Object getX() {
return x;
}
public Object getY() {
return y;
}
}
这种做法是基本满足使用要求,但是如果在某些情况下,很容易发生Object向下转型带来的问题,如以下代码:
public static void main(String[] args) {
Point point = new Point();
point.setX(1);
point.setY(2);
Float x = (Float) point.getX();
Float y = (Float) point.getY();
}
运行时就会发错误(如下图),即类型转化所带来的问题,并且这种错误,在编译时不会显示出来,只会在运行时显示,所以针对这种情况java引进了泛型。
所以如果使用泛型改写上述代码就应该是这样
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 x;
}
public T getY() {
return y;
}
}
使用起来就变成了这样Point<Integer>point = new Point<>()
,如果这时候调用如果类型不对,会在编译的时候就爆出错误(如下图),方便开发人员及时的处理错误。
另外如果申明了泛型,但是使用时不加<类型>
,java还是会把里面的T当作Object处理,如上面的Point<Integer>point = new Point<>()
,我这样用Point point = new Point()
,并不会报错,而且会把x、y直接当作Object类型,也算时一种向下兼容,防止以前写的代码出问题。
二、泛型的使用
1.泛型类
泛型类使用起来比较简单,如上面的Point,就是泛型类的一种使用,不过需要注意的是泛型的参数字母可以任意定义,并且参数数量爷没有什么限制,在这里就不过多举例。
2.泛型接口
泛型接口定义和泛型类相似,可以参考如下代码
interface IMessage<T>{
public void print(T t);
}
但是值得注意的是,接口实现时,有两种方式:
- 继续使用泛型
class IMessageImp <T> implements IMessage<T>{
@Override
public void print(T t) {
// TODO Auto-generated method stub
}
}
- 使用具体的类型
class IMessageImp implements IMessage<String>{
@Override
public void print(String t) {
// TODO Auto-generated method stub
System.out.println(t);
}
}
两种方式都有使用,需要都掌握
3.泛型方法
泛型方法,个人感觉使用应该不多,但是有必要了解一下,因为在jdk文档当中有一些这样的例子。
public <T> T[] fun(T...t){
return t;
}
4.通配符
通配符是为了配合泛型类等做参数而使用的,为了防止函数只能对一个具体的参数进行处理而产生的。类型通配符一般是使用?
代替具体的类型参数。例如 List 在逻辑上是List,List 等所有List<具体类型实参>的父类。
public static void getData(List<?> data) {
System.out.println("data :" + data.get(0));
}
除了上述的?
通配符,还衍生出了如下两个通配符:
-
?extends
:设置泛型上限,参数和方法申明上都可以使用如:
?extends Number
,表示只能设置Number或者其子类,例如:Integer、Double,就是说泛型的上限就是Number
class Point<T extends Number >{
private T x;
private T y;
}
public void fun(List<? extends Number> list){
//无实际意义,只是简单举例
}
-
?super
:设置泛型下限,只能设置在参数上如:
?super String
,表示只能设置String或者其父类,例如:Object,就是说泛型的下限就是String
public void fun(List<?super Number> list){
//无实际意义,只是简单举例
}
总结
java泛型以前有所了解但是使用不多,这次系统的复习一下,做个小结。