Java里面的泛型在實際開發中運用的很多,學過C++的同學一定知道C++的模板,而Java中的泛型,一定程度上和它還是挺像的。
相信寫Java的人,大都有用過List的實作類ArrayList。在Java沒有泛型之前,它的內部是一個Object的陣列實作的。這也導致一個問題,每次使用里面的元素的時候需要向下轉型,而且很明顯,如果是Object的話,意味著我們可以丟任何物件進去。自動轉型成Object,這樣在使用的時候就很容易出問題,不知道里面存的是什么。如:
ArrayList list = new ArrayList();
list.add("string1");
list.add("string2");
String str = (String) list.get(0);
list.add(new File("test.txt"));
然而使用泛型容易,我們就經常使用List的泛型,但是如果我們要寫一個泛型的類其實并不那么容易。
最簡單的泛型
package io.ilss.advanced.generic;
public class MyObject<T> extends BaseData {
private T valueOne;
private T valueTwo;
public MyObject(T valueOne, T valueTwo) {
this.valueOne = valueOne;
this.valueTwo = valueTwo;
}
public T getValueOne() {
return valueOne;
}
public void setValueOne(T valueOne) {
this.valueOne = valueOne;
}
public T getValueTwo() {
return valueTwo;
}
public void setValueTwo(T valueTwo) {
this.valueTwo = valueTwo;
}
public static void main(String[] args) {
MyObject<String> object = new MyObject<>("String one!", "String two");
System.out.println("value one " + object.valueOne + " value two " + object.valueTwo);
}
}
在MyObject中引入一個型別變數T,用尖括號<>括起來,放在類名的后面。如上!在定義的時候可以有多個型別的變數,在<>中以逗號,分隔例如public class MyObject<T, U>{…},在類中如果要使用型別 就直接把定義的型別變數看做類名使用即可。
用泛型做一個介面回傳類
相信寫Java的程式員都寫過Web介面,那我們用泛型來封裝一個統一回應回傳的類ResponseMsg。
package io.ilss.advanced.generic;
public class ResponseMsg<T extends BaseData> {
public static int SUCCESS_CODE = 1;
public static int ERROR_CODE = 0;
public static int OTHER_CODE = -1;
private int code;
private String msg;
private T data;
public static <U extends BaseData> ResponseMsg sendSuccess(U data) {
ResponseMsg<U> responseMsg = new ResponseMsg<>();
responseMsg.code = SUCCESS_CODE;
responseMsg.data = data;
responseMsg.msg = "Remote Call Success!";
return responseMsg;
}
public static <U extends BaseData> ResponseMsg sendError(U data, String msg) {
ResponseMsg<U> responseMsg = new ResponseMsg<>();
responseMsg.code = ERROR_CODE;
responseMsg.data = data;
responseMsg.msg = "Remote Call Error";
return responseMsg;
}
public static <U extends BaseData> ResponseMsg sendOther(U data, String msg) {
ResponseMsg<U> responseMsg = new ResponseMsg<>();
responseMsg.code = OTHER_CODE;
responseMsg.data = data;
responseMsg.msg = msg;
return responseMsg;
}
public static void main(String[] args) {
System.out.println(ResponseMsg.<MyObject>sendSuccess(new MyObject<String>("asdf","asfd")));
}
public String toString() {
return "ResponseMsg{" +
"code=" + code +
", msg='" + msg + '\'' +
", data="https://bbs.csdn.net/topics/ + data +
'}';
}
}
上面的重點是上的<U>我利用靜態方法封裝了ResponseMsg的構建,只需要提供靜態方法讓呼叫的人傳入一個類,也可以不用寫Getter Setter方法,或者直接變成私有方法。
方法如果要用泛型,則只需要在定時的時候在回傳型別前面加上<T>即可使用。呼叫的時候直接在呼叫方法前面用<>傳入你想用的類即可。如上所示,也可以將方法用的泛型直接傳入自己類定義的泛型。
此外還可以通過extends限定你是某某類的子類,或者實作了某個介面。如果有多個介面可以用&連接,比如<T extends Comparable & Serializable>,如果有多個泛型可以是這樣<T extends OneObject, U extends TwoObject>
泛型不能直接new,需要外部傳入。
如:
T data = new T(); //這是不被允許的,不能實體化物件
T[] arr = new T[10]; //這也是不被允許的 不能構造泛型陣列
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/269592.html
標籤:Java相關
