泛型入门
為什么使用泛型
要求設計出一個可以表示坐標點的類,坐標由X和Y組成。
坐標表示方法:
整數:x=10,Y=20;
小數:X=10.5,Y=20.6
字符串:X="東經180度",Y=“北緯30度”
問,此類怎么設計。
題目分析
肯定要設計表示坐標點的類。類名稱:Point。
但是坐標的X,Y保存的數據類型有三種(int,float,String),要想使用一個類可以同時接收這三種類型,則現在只能使用Object類,因為Object可以接受任何類型的
數據,都會自動發生向上轉型。這樣三種數據類型會發生以下轉變:
數字(int)->自動裝箱成(Integer)->向上轉型Object接收 小數點(float)->自動裝箱成(Float)->向上轉型Object接收 字符串(String)->向上轉型Object接收Point類:
class Point{private Object x ; // 表示X坐標private Object y ; // 表示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 ;} };總體代碼如下:需要注意向上轉型和向下轉型的自動裝箱和自動拆箱操作。
class Point{private Object x ; // 表示X坐標private Object y ; // 表示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 ;} };public class GenericsDemo01{public static void main(String args[]){Point p = new Point() ; // 聲明一個Point的對象p.setX(10) ; // 利用自動裝箱操作:int --> Integer --> Objectp.setY(20) ; // 利用自動裝箱操作:int --> Integer --> Objectint x = (Integer)p.getX() ; // 取出數據先變為Integer,之后自動拆箱,Integer-->intint y = (Integer)p.getY() ; // 取出數據先變為Integer,之后自動拆箱System.out.println("整數表示,X坐標為:" + x) ;System.out.println("整數表示,Y坐標為:" + y) ;} };以上代碼存在很大問題,加設里面的數據類型變換一下,則則自動拆箱操作處就要修改強制轉型代碼。
認識泛型
是在類聲明的時候,通過一個標識表示類中某個屬性的類型或者是某個方法的返回值及參數類型。這樣在類聲明和實例化的時候只要指定好要使用的類型即可。
泛型定義實例:
class Point<T>{ // 此處可以隨便寫標識符號,T是type的簡稱private T var ; // var的類型由T指定,即:由外部指定public T getVar(){ // 返回值的類型由外部決定return var ;}public void setVar(T var){ // 設置的類型也由外部決定this.var = var ;} };結合上面完整的一個例子:
class Point<T>{ // 此處可以隨便寫標識符號,T是type的簡稱private T var ; // var的類型由T指定,即:由外部指定public T getVar(){ // 返回值的類型由外部決定return var ;}public void setVar(T var){ // 設置的類型也由外部決定this.var = var ;} }; public class GenericsDemo06{public static void main(String args[]){Point<String> p = new Point<String>() ; // 里面的var類型為String類型p.setVar("MLDN") ; // 設置字符串System.out.println(p.getVar().length()) ; // 取得字符串的長度 } };可以更好的保護數據類型。
通過泛型就可以直接修改之前的程序。
修改結果如下:
class Point<T>{private T x ; // 表示X坐標private T y ; // 表示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 ;} };public class GenericsPoint{public static void main(String args[]){Point<Integer> p = new Point<Integer>() ;p.setX(10) ; // 利用自動裝箱操作:int --> Integerp.setY("北緯210度") ; // 利用自動裝箱操作:int --> Integerint x = p.getX() ; // 自動拆箱int y = p.getY() ; // 自動拆箱System.out.println("整數表示,X坐標為:" + x) ;System.out.println("整數表示,Y坐標為:" + y) ;} };在這樣的程序中,減少了類型轉換的操作(不用用一個Object類在類中定義,不用向上轉型,向下轉型,拆箱,裝箱)。
構造方法中使用泛型
泛型也可以在構造方法中使用,一般有可能為構造方法為類中屬性賦值。
為構造方法屬性賦值實例:
class Point<T>{ // 此處可以隨便寫標識符號,T是type的簡稱private T var ; // var的類型由T指定,即:由外部指定 public Point(T var){ // 通過構造方法設置內容this.var = var ;}public T getVar(){ // 返回值的類型由外部決定return var ;}public void setVar(T var){ // 設置的類型也由外部決定this.var = var ;} }; public class GenericsDemo08{public static void main(String args[]){Point<String> p = new Point<String>("MLDN") ; // 里面的var類型為String類型System.out.println("內容:" + p.getVar()) ;} };指定兩個泛型類型,如下:
class Notepad<K,V>{ // 此處指定了兩個泛型類型private K key ; // 此變量的類型由外部決定private V value ; // 此變量的類型由外部決定public K getKey(){return this.key ;}public V getValue(){return this.value ;}public void setKey(K key){this.key = key ;}public void setValue(V value){this.value = value ;} }; public class GenericsDemo09{public static void main(String args[]){Notepad<String,Integer> t = null ; // 定義兩個泛型類型的對象t = new Notepad<String,Integer>() ; // 里面的key為String,value為Integert.setKey("李興華") ; // 設置第一個內容t.setValue(30) ; // 設置第二個內容System.out.print("姓名;" + t.getKey()) ; // 取得信息System.out.print(",年齡;" + t.getValue()) ; // 取得信息 } };泛型的安全警告
在泛型應用中最好在聲明類對象的時候指定其內部的數據類型。例如:“Info<String>”,但是也可不指定類型。
package Thread1; class Info<T>{private T var ;public T getVar(){return this.var ;}public void setVar(T var){this.var = var ;}public String toString(){ // 覆寫Object類中的toString()方法return this.var.toString() ;} }; public class demo1{public static void main(String args[]){ Info i = new Info() ; // 警告,沒有指定泛型類型 i.setVar("MLDN") ; // 設置字符串System.out.println("內容:" + i.getVar()) ;} };運行結果:
內容:MLDN程序不會影響執行,但是在Info類中并沒有指定泛型類型,則在java中為了保證程序依然可以運行,會將T自動設置成Object類型。這樣一來就可以接受任意數據類型。
也就是說,此時的var類型就是Object,所有的泛型信息將被擦除。
以上程序相當于以下定義:
class Info<T>{private T var ;public T getVar(){return this.var ;}public void setVar(T var){this.var = var ;}public String toString(){ // 覆寫Object類中的toString()方法return this.var.toString() ;} }; public class GenericsDemo11{public static void main(String args[]){ Info<Object> i = new Info<Object>() ; // 指定Object為泛型類型i.setVar("MLDN") ; // 設置字符串System.out.println("內容:" + i.getVar()) ;} };?
總結
- 上一篇: Java设计模式—责任链模式
- 下一篇: 日志分析logstash插件-grok详