在講解泛型之前,先看看下面一個實例。
現在要求設計一個可以表示出座標點的類,座標有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進行接收,造成了類型的安全問題,那麼可以使用泛型進行解決。