1. 程式人生 > >JDK1.5--)很重要的特性——泛型

JDK1.5--)很重要的特性——泛型

JDK1.5–)很重要的特性——泛型

首先我們要了解:什麼是向下轉型和向上轉型。

  • 面向物件的轉型只會發生在具有繼承關係的父子類中(介面也是繼承的一種)
  • 向上轉型:其核心目的在於引數的統一上,根本不需要強制型別轉換。
  • 向下轉型:是為了操作子類定義的特殊功能,需要強制型別轉換,可是現在存在的問題是:向下轉型其實是一種非常不安全的操作,以為編譯的時候,程式不會報錯,而在執行的時候會報錯,這就是傳說中的—迷之報錯。
  • 不過呢,在JDK1.5之後,新增加了泛型的技術,這就將上述向下轉型的問題消滅在了萌芽之中。
  • 泛型的核心意義在於:類在進行定義的時候可以使用一個標記,此標記就表示類中屬性或者方法以及引數的型別,標記在使用的時候,才會去動態的設定型別。
  • -
  • 原始碼如下:
    首先來看看:座標程式碼滿足整型:
package cn.dujiang.demo;
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 Object getX() {
        return x;
    }
    public
Object getY() { return y; } } public class TestDemo { public static void main(String[] args) { //1.設定資料 Point p = new Point() ; p.setX(10); p.setY(20); //2.取出資料 int x = (Integer) p.getX(); int y = (Integer) p.getY(); System.out
.println("x地置"+ x +",y地置"+ y); } }

座標程式碼滿足字串的:

package cn.dujiang.demo;
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 Object getX() {
        return x;
    }
    public Object getY() {
        return y;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        //1.設定資料
        Point p = new Point() ;
        p.setX("東經:100°");
        p.setY("北緯:20°");
        //2.取出資料
        String x = (String) p.getX();
        String y = (String) p.getY();
        System.out.println("x地置"+ x +",y地置"+ y);
   }
}

再來看看:泛型的基本表現形式:

package cn.dujiang.demo;
//此時設定的T在Point類定義上,只表示一個標記,在使用的時候需要為其設定具體的型別
class Point<T> {  //定義座標,這個"<>"裡面的東西隨意,Type = T,是表示一種型別
    private T x ;  //此屬性的型別不確定,由Point類使用時動態決定
    private T y ;  //此屬性的型別不確定,由Point類使用時動態決定
    public void setX(T x) {
        this.x = x;
    }
    public void setY(T y) {
        this.y = y;
    }
    public T getX() {
        return x;
    }
    public T getY() {
        return y;
    }
}
//在使用Point類的時候才設定標記的內容,也就是設定了類中的屬性的型別。
//下面用String試試:
public class TestDemo {
    public static void main(String[] args) {
        //1.設定資料
        Point<String> p = new Point<>() ;  //JDK1.7之後例項化的泛型可以省略。
        //加入設定的資料型別是錯誤的,那麼在編譯的時候就會自動的排查了
        p.setX("東經:10°");
        p.setY("北緯:20°");
        //2.取出資料,由於我們接收的型別就是String,所以不需要向下強制轉換
        String x =  p.getX();
        String y =  p.getY();
        System.out.println("x地置"+ x +",y地置"+ y);
   }
}
//輸出之後發現,所有類中屬性的型別,都是動態設定的,而所有使用泛型標記的方法引數型別也都發生改變,這樣
//就相當於避免了向下轉型的問題,從而解決了轉換的安全問題

泛型的萬用字元:

package cn.dujiang.demo;
class Message<T> {
    private T msg ;
    public void setMsg(T msg) {
        this.msg = msg;
    }
    public T getMsg() {
        return msg;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Message<Integer> m1 = new Message<Integer>();
        Message<String> m2 = new Message<String>();

        m1.setMsg(10);
        m2.setMsg("Hello World");
        fun(m1) ;//引用傳遞
        fun(m2) ;
    }
    public static void fun(Message temp){
        System.out.println(temp.getMsg());
    }
}

/*以上程式碼為Message類設定的是一個String型的泛型型別,但是如果說
現在設定的型別變了,那麼fun()方法裡面接收的"Message<String>"那麼就不能夠使用了,並且
fun()方法不能夠針對不同的泛型進行過載,因為方法的過載認的只是引數的型別,與泛型無關
解決方法1.不設定泛型引數的泛型
*/

在介面上必須定義其相應的子類,如果要定義子類有以下兩種方式:

  1. 在子類上不設定泛型,但是在父類介面上要明確定義一個泛型。程式碼如下:
package cn.dujiang.demo;

    interface IMessage<T>{//設定泛型介面
    public void print(T t) ;
}
//子類也繼續使用泛型,並且父介面使用和子類同樣的泛型標記
class MessageImpl implements IMessage<String> {

    @Override
    public void print(String t) {
        // TODO Auto-generated method stub
        System.out.println(t);
    }

}
public class TestDemo {
    public static void main(String[] args) {
        IMessage<String> msg = new MessageImpl();
        msg.print("Hello World!") ;
    }
}

  1. 在子類上繼承例項化泛型
package cn.dujiang.demo;

interface IMessage<T>{//設定泛型介面
    public void print(T t) ;
}
//子類也繼續使用泛型,並且父介面使用和子類同樣的泛型標記
class MessageImpl<T> implements IMessage<T> {
    public void print(T t){
        System.out.println(t);
    }

}
public class TestDemo {
    public static void main(String[] args) {
        IMessage<String> msg = new MessageImpl<String>();
        msg.print("Hello World!") ;
    }
}

總結:泛型主要針對向下轉型時所帶來的安全隱患,其核心組成是在宣告類或介面時,不設定引數或屬性的型別。