在讲解泛型之前,先看看下面一个实例。
现在要求设计一个可以表示出坐标点的类,坐标有X和Y组成,坐标的表示方法有以下三种:
1. 整数表示法: X=10、Y=20
2. 小数表示法: X=10.5、Y=20.6
3. 字符串表示法: X=“东经180度”、Y=“北纬210度”
看到如上的要求,读者首先就要考虑到,必须建立一个坐标的类Point,此类中有两个属性分别用来表示X和Y坐标,但是X和Y中保存的数据类型会有三种形式(int、float、String),所以想使用一种类型同时接受三种数据类型,只能使用Object,因为Object类可以接受任何类型的数据,都会自动发生向上转型操作,这样三种数据类型就将按照以下方式进行转换:
1. 数字(int)–>自动装箱成Integer–>向上转型使用Object接收
2. 小数(float)–>自动装箱成Float–>向上转型使用Object接收
3. 字符串(String)–>向上转型使用Object接收
按照此思路设计,Point代码如下:
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 void getX(){
return this.x;
}
public void getY(){
return this.y;
}
};
以上程序定义Point属性时使用了Object类型,则输入的数据可以是任意的类型,下面就使用不同类型进行验证:
【使用整数类型】
public class GenericsDemo01
{
public static void main(String args[])
{
Point p=new Point();
p.setX(10);
p.setY(20);
int x=(Integer)p.getX();
int y=(Integer)p.getY();
System.out.println("整数表示,X坐标为:"+x);
System.out.println("整数表示,Y坐标为:"+y);
}
}
运行结果:
整数表示,X坐标为:10
整数表示,Y坐标为:20
以上程序中设置的x和y坐标的内容是数字,所以会自动发生装箱的操作,并将Integer的对象利用向上转型的关系为object类型以完成功能,下面使用小数进行验证:
【使用小数表示坐标】
public class GenericsDemo01
{
public static void main(String args[])
{
Point p=new Point();
p.setX(10.5f);
p.setY(20.6f);
float x=(Float)p.getX();
float y=(Float)p.getY();
System.out.println("小数表示,X坐标为:"+x);
System.out.println("小数表示,Y坐标为:"+y);
}
}
运行结果:
小数表示,X坐标为:10.5
小数表示,Y坐标为:20.6
String类型的测试同理不在叙述。
以上测试程序证明了Point类确实符合设计要求,但是以上的实现是否存在问题?
仔细想一下,Object类可以接收任意类型的子类对象,那么也就是说可以把X坐标设置为数字,而把Y坐标设置为字符串,在编译时并不会出现错误,
Point p=new Point();
p.setX(10.5f);
p.setY("北京");
float x=(Float)p.getX();
float y=(Float)p.getY();
System.out.println("小数表示,X坐标为:"+x);
System.out.println("小数表示,Y坐标为:"+y);
但是在程序运行时却会出现错误:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Float
at GenericsDemo01.main(GenericsDemo01.java:27)
程序出现了转换异常,因为设置的String类型无法向Float类型转换,之所以造成这样的问题是因为Point类中属性使用了Object进行接收,造成了类型的安全问题,那么可以使用泛型进行解决。