本篇內(nèi)容介紹了“Java泛型的實(shí)際應(yīng)用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
十余年的廈門網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營(yíng)銷型網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整廈門建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“廈門網(wǎng)站設(shè)計(jì)”,“廈門網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
Java有很多的高級(jí)特性,泛型是其中之一,泛型即參數(shù)化類型。關(guān)于泛型的概念,有很多文章都有介紹,這里就不再過(guò)多的介紹了。本文將從實(shí)戰(zhàn)的角度,來(lái)看看泛型在實(shí)際項(xiàng)目中的使用
1 泛型在框架中的使用
泛型在框架中及為常見(jiàn),我們?cè)谑褂酶鞣N框架的時(shí)候,都會(huì)使用到泛型,具體看下面的例子。
1.1 集合框架中使用泛型
這是最常見(jiàn)的泛型的使用場(chǎng)景,比如下面的代碼
List list1 = new ArrayList<>();
List list2 = new ArrayList<>();
list1和list2雖然都是列表類型,但是列表里面存的數(shù)據(jù)可以是String,可以是Integer,也可以是自定義類型。集合中存放的數(shù)據(jù),在定義的時(shí)候不能確定是什么類型,只有當(dāng)使用集合時(shí),才能確定放什么類型的數(shù)據(jù)。所以在集合的定義中,就用泛型來(lái)代表集合里面的數(shù)據(jù)。
1.2 fastjson框架中使用泛型
alibaba的fastjson很多人應(yīng)該都用過(guò),fastjson很多地方也用到了泛型,比如將json字符串轉(zhuǎn)成對(duì)象,如下的例子
// 將userStr字符串映射成UserDto類
String userStr = "{id: '123', name: '張三'}";
UserDto userDto = JSON.parseObject(userStr, UserDto.class);
JSON類中,對(duì)parseObject方法的定義,如下
public static T parseObject(String text, Class clazz) {
return parseObject(text, clazz);
}
parseObject方法中的參數(shù)傳遞用到了泛型,要把json字符串轉(zhuǎn)成什么類,在定義的時(shí)候并不知道,只有在用到的時(shí)候,才知道具體的類型。
1.3 泛型使用場(chǎng)景總結(jié)
綜合集合框架和JSON框架的例子,我們可以大概總結(jié)出泛型的使用場(chǎng)景,便于理解:不管是數(shù)據(jù)存儲(chǔ)還是參數(shù)傳遞,定義的時(shí)候,類型并不確定,只有到使用的時(shí)候,才知道具體的類型。所以我們的項(xiàng)目中,如果有用到這種不確定類型的時(shí)候,就可以考慮泛型。
當(dāng)然,泛型還有更多的使用場(chǎng)景,比如泛型接口,這里就不一一舉例了。
2 泛型的實(shí)戰(zhàn)應(yīng)用
2.1 數(shù)據(jù)的存儲(chǔ)使用泛型類
在實(shí)際項(xiàng)目開(kāi)發(fā)中,有一種場(chǎng)景:前后端分離時(shí),為了方便前后端的對(duì)接,一般會(huì)統(tǒng)一定義參數(shù)的傳遞格式和結(jié)果的返回格式。以結(jié)果返回為例,一般都會(huì)定義【返回碼】,【返回描述】,【返回?cái)?shù)據(jù)】等,所以可以定義一個(gè)ResponseDto類,如下:
public class ResponseDto {
/**
* 返回碼
*/
private String code;
/**
* 返回信息
*/
private String message;
/**
* 返回?cái)?shù)據(jù),???,應(yīng)該定義成什么類型呢?
*/
private ??? content;
// 省略set get
...
}
【返回碼】一般是前后端約好的字符串類型,【返回描述】一般就是字符串類型,【返回?cái)?shù)據(jù)】就不一定了,如果是查詢類的請(qǐng)求,返回的數(shù)據(jù)就是列表信息,可能還包含分頁(yè)信息;如果是保存、刪除之類的請(qǐng)求,返回的數(shù)據(jù)可能是一條數(shù)據(jù),也可能只是ID,也可能不需要返回?cái)?shù)據(jù)。所以【返回?cái)?shù)據(jù)】這個(gè)字段就是個(gè)不確定的類型,可以定義成泛型。所以我們就可以把ResponseDto類改成下面這樣:
public class ResponseDto {
/**
* 返回碼
*/
private String code;
/**
* 返回信息
*/
private String message;
/**
* 返回?cái)?shù)據(jù)
*/
private T content;
}
使用的方法如下:
// 返回單個(gè)UserDto對(duì)象
ResponseDto responseDto = new ResponseDto<>();
responseDto.setContent(userDto); // userDto是已有的變量
// 返回UserDto列表
ResponseDto> responseDto = new ResponseDto<>();
responseDto.setContent(userDtoList); // userDtoList是已有的變量
// 返回ID
ResponseDto responseDto = new ResponseDto<>();
responseDto.setContent(id); // id是已有的變量
這個(gè)類就叫做泛型類。
2.2 參數(shù)的傳遞使用泛型方法
以BeanUtils.copyProperties為例,大家應(yīng)該對(duì)這個(gè)方法不陌生,就是將一個(gè)實(shí)體類中的屬性值,拷貝到另一個(gè)實(shí)體類中。一般我們的使用方法是這樣的:
// 功能:將UserDto數(shù)據(jù)拷貝到User
User user = new User();
BeanUtils.copyProperties(userDto, user); // userDto是已有的變量
但是每次都要寫兩行代碼有點(diǎn)麻煩,要先new一個(gè)新的實(shí)體類,再往里面拷數(shù)據(jù)。于是我封裝了個(gè)通用的工具類
public class CopyUtil {
/**
* CopyUtil.copy的定義很類似JSON.parseObject的定義
*/
public static T copy(Object source, Class clazz) {
if (source == null) {
return null;
}
T obj = null;
try {
obj = clazz.newInstance(); // 生成一個(gè)實(shí)例
} catch (Exception e) {
e.printStackTrace();
}
BeanUtils.copyProperties(source, obj);
return obj;
}
}
同樣是上面的例子,用工具類的寫如下
User user = CopyUtil.copy(userDto, User.class); // userDto是已有的變量
CopyUtil.copy的定義很類似JSON.parseObject的定義。代碼變成了一行,當(dāng)然,減少一行也不足以將其封裝成一個(gè)工具類。再來(lái)看一個(gè)場(chǎng)景,列表的拷貝,用BeanUtils.copyProperties的寫法如下
// 功能:將List數(shù)據(jù)拷貝到List
List userList = new ArrayList<>();
// userDtoList是已有的變量
for (int i = 0, l = userDtoList.size(); i < l; i++) {
UserDto userDto = userDtoList.get(i);
User user = new User();
BeanUtils.copyProperties(userDto, user);
userList.add(user);
}
這樣的代碼量就比較多了,并且代碼寫法比較固定。如果項(xiàng)目中用到列表復(fù)制的功能比較多,那就有必要對(duì)其進(jìn)行封裝了,如下的copyList方法:
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author 甲蛙
*/
public class CopyUtil {
/**
* 列表復(fù)制
*/
public static List copyList(List source, Class clazz) {
List target = new ArrayList<>();
if (!CollectionUtils.isEmpty(source)){
if (!CollectionUtils.isEmpty(source)){
for (Object c: source) {
T obj = copy(c, clazz);
target.add(obj);
}
}
}
return target;
}
/**
* 單體復(fù)制
*/
public static T copy(Object source, Class clazz) {
if (source == null) {
return null;
}
T obj = null;
try {
obj = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
BeanUtils.copyProperties(source, obj);
return obj;
}
}
用法很簡(jiǎn)單,還是以上面的列表復(fù)制為例,代碼就變成這樣:
// 功能:將List數(shù)據(jù)拷貝到List
List userList = CopyUtil.copyList(userDtoList, User.class);
封裝成CopyUtil工具類后,不管是單體復(fù)制還是列表復(fù)制,都只需要一行代碼,省去了大量的重復(fù)代碼,從而提高開(kāi)發(fā)效率,這里的copy方法和copyList方法,就是泛型方法,在方法的參數(shù)中使用了泛型。
當(dāng)然這個(gè)工具類有個(gè)缺點(diǎn),就是用到了反射,會(huì)犧牲一點(diǎn)性能,不過(guò)這點(diǎn)性能對(duì)于大部分的項(xiàng)目來(lái)說(shuō)可以忽略不計(jì)。
2.3 總結(jié)
本文討論了兩種泛型的實(shí)戰(zhàn)應(yīng)用,一種是用來(lái)存儲(chǔ)類型不確定的數(shù)據(jù),用到泛型類;一種是用來(lái)傳遞類型不確定的參數(shù),用到了泛型方法。當(dāng)然,泛型還有更多的用法,比如泛型接口,比較典型的是比較器接口Comparable,這里就不再展開(kāi)了。
“Java泛型的實(shí)際應(yīng)用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!