Java泛型簡單的使用
Github:https://github.com/imyiren/java-base-ilss
前言
Java里面的泛型在實際開發(fā)中運用的很多谓形,學(xué)過C++的同學(xué)一定知道C++的模板汹来,而Java中的泛型笋颤,一定程度上和它還是挺像的直秆。
相信寫Java的人瞄崇,大都有用過List的實現(xiàn)類ArrayList昂勒。在Java沒有泛型之前闸翅,它的內(nèi)部是一個Object的數(shù)組實現(xiàn)的。這也導(dǎo)致一個問題辜伟,每次使用里面的元素的時候需要向下轉(zhuǎn)型氓侧,而且很明顯脊另,如果是Object的話,意味著我們可以丟任何對象進(jìn)去约巷。自動轉(zhuǎn)型成Object偎痛,這樣在使用的時候就很容易出問題,不知道里面存的是什么独郎。如:
ArrayList list = new ArrayList();
list.add("string1");
list.add("string2");
String str = (String) list.get(0);
list.add(new File("test.txt"));
然而使用泛型容易踩麦,我們就經(jīng)常使用List的泛型,但是如果我們要寫一個泛型的類其實并不那么容易氓癌。
最簡單的泛型
package io.ilss.advanced.generic;
/**
* className MyObject
* description MyObject
*
* @author feng
* @version 1.0
* @date 2019-01-24 18:32
*/
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接口,那我們用泛型來封裝一個統(tǒng)一響應(yīng)返回的類ResponseMsg返奉。
package io.ilss.advanced.generic;
/**
* className ResponseMsg
* description ResponseMsg
*
* @author feng
* @version 1.0
* @date 2019-01-24 18:47
*/
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")));
? ? }
? ? @Override
? ? public String toString() {
? ? ? ? return "ResponseMsg{" +
? ? ? ? ? ? ? ? "code=" + code +
? ? ? ? ? ? ? ? ", msg='" + msg + '\'' +
? ? ? ? ? ? ? ? ", data=" + data +
? ? ? ? ? ? ? ? '}';
? ? }
}
上面的重點是上的<U>我利用靜態(tài)方法封裝了ResponseMsg的構(gòu)建,只需要提供靜態(tài)方法讓調(diào)用的人傳入一個類娜膘,也可以不用寫Getter Setter方法,或者直接變成私有方法。
方法如果要用泛型优质,則只需要在定時的時候在返回類型前面加上<T>即可使用竣贪。調(diào)用的時候直接在調(diào)用方法前面用<>傳入你想用的類即可。如上所示巩螃,也可以將方法用的泛型直接傳入自己類定義的泛型演怎。
此外還可以通過extends限定你是某某類的子類,或者實現(xiàn)了某個接口避乏。如果有多個接口可以用&連接爷耀,比如<T extends Comparable & Serializable>,如果有多個泛型可以是這樣<T extends OneObject, U extends TwoObject>
注意
泛型不能直接new拍皮,需要外部傳入歹叮。
如:
T data = new T();? ? //這是不被允許的,不能實例化對象
T[] arr = new T[10];? //這也是不被允許的? 不能構(gòu)造泛型數(shù)組
JAVA
相關(guān)推薦
我的編程能力是怎樣突飛猛進(jìn)的
閱讀 13150
面試官問我:Object o = new Object() 占用了多少個字節(jié)铆帽?
閱讀 7936
活久見咆耿,大佬4面字節(jié)暢通無阻直接拿offer,附上大佬的面試感悟爹橱!
閱讀 237
今年我讀了四個開源項目的源碼萨螺,來分享下心得
閱讀 34124
新來的小哥這樣寫代碼!同事直呼“中毒了”
閱讀 4094