在講解泛型之前,先看看下面一個執行個體。
現在要求設計一個可以表示出坐标點的類,坐标有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();
p.setY();
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(f);
p.setY(f);
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(f);
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:)
程式出現了轉換異常,因為設定的String類型無法向Float類型轉換,之是以造成這樣的問題是因為Point類中屬性使用了Object進行接收,造成了類型的安全問題,那麼可以使用泛型進行解決。