一、什么是泛型
泛型可以理解为任何类型,即不要求指定类型,给定任意一个类型都可以。 在不确定具体类型的时候可以使用,和使用object类相比没有类型转换错误
例如,ArrayList使用了泛型
ArrayList<Integer>
ArrayList<String>
书面话的定义
泛型,即参数化的类型
参数化的类型:将类型由原来的具体类型参数化,类似于方法中的变量参数,此时类型也可以定义成参数形式(也可以成为类型形参) 在使用和调用时传入具体的类型(实参)
泛型的本质时参数化类型,也就是说在泛型使用过程中操作的数据类型被指定为一个参数,这种参数类型可以用于类,接口和方法中。
使用泛型的好处
- 类型安全,放置什么类型,取出来就是什么类型,不存在ClassCastException类型转换异常
-例子:
List arrayList = new ArrayList();
arrayList.add("dasdsd");
arrayList.add(100);
for(int i=0;i<arrayList.size();i++){
String item = (String)arrayList.get(i);
}
运行结果:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
虽然ArrayList可以放置任意类型的数据,但是因为放置的类型不同,使用时都按照String使用,程序会报错。为了解决运行时报错的问题,可以在编译阶段就进行报错,使用泛型来解决
List<String> arrayList = new ArrayList<String>();
...
//arrayList.add(100); 在编译阶段,编译器就会报错
- 提升程序的可读性,在编程阶段就可以显示的知道泛型方法、泛型集合等要处理的对象类型
- 不使用泛型可能写着写着就不知道里面放的是什么类型了!
- 代码复用,合并了同类型的代码
- 例如:需要实现一个坐标类,分别设置Integer和Float类型的点坐标
- 如果没有泛型则需要写两个类
//设置Integer类型的点坐标
class IntegerPoint{
private Integer x ; // 表示X坐标
private Integer y ; // 表示Y坐标
public void setX(Integer x){
this.x = x ;
}
public void setY(Integer y){
this.y = y ;
}
public Integer getX(){
return this.x ;
}
public Integer getY(){
return this.y ;
}
}
//设置Float类型的点坐标
class FloatPoint{
private Float x ; // 表示X坐标
private Float y ; // 表示Y坐标
public void setX(Float x){
this.x = x ;
}
public void setY(Float y){
this.y = y ;
}
public Float getX(){
return this.x ;
}
public Float getY(){
return this.y ;
}
}
除了变量的类型不同外,其他的完全相同。【泛型参数化的类型】
如果不使用泛型 可以用object类型来解决,但是可能会存在泛型不安全问题
class ObjectPoint{
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 this.x ;
}
public Object getY(){
return this.y ;
}
}
即用Object来代替子类型 设置时可以直接放入,取出时需要强制类型转换【可能出现类型转化错误】
ObjectPoint integerPoint = new ObjectPoint();
integerPoint.setX(new Integer(100)); //设置值
//取出值需要强制类型转换
Integer integerX=(Integer)integerPoint.getX();
如果忘记放入的类型了,在取出时转换成了其他类型(比如存入Integer但是取出时强制转化成了String)此时编译时不会报错,但是运行时会报类型转化错误【所以类型不安全】
这个列子可以帮助理解 泛型是类型安全,和可以复用代码的好处。
二、各种泛型定义以及使用
1. 泛型类定义及使用
//定义
class point<T>{
}
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 ;
}
};
//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.12f)) ;
System.out.println(p.getX());
(1) 定义泛型类
在类名后面加 尖括号 里面一个大写字母 ,大写字母可以为任意
(2)在类中使用泛型
这个T表示派生自Object类的任意类型。【可以把它当成一个具体的类在需要的地方使用使用,比如String】
在类中具体使用:
//定义变量
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());
和一般类构建不同,多了
可以定义有多个泛型变量的类(参照HashMap)
定义方法
class MorePoint<K,V>{
}