Java對(duì)象轉(zhuǎn)換的實(shí)現(xiàn)方式匯總
Java對(duì)象轉(zhuǎn)換的多種實(shí)現(xiàn)方式
在Java開(kāi)發(fā)中,對(duì)象轉(zhuǎn)換是一個(gè)常見(jiàn)的需求。特別是在不同層次間傳遞數(shù)據(jù)時(shí),通常需要將一個(gè)對(duì)象轉(zhuǎn)換為另一個(gè)對(duì)象。雖然JSON序列化/反序列化是一種常見(jiàn)的方法,但在某些場(chǎng)景下可能并不是最佳選擇。本文將總結(jié)幾種常見(jiàn)的Java對(duì)象轉(zhuǎn)換實(shí)現(xiàn)方式,并提供選擇建議。
| 技術(shù)/工具 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場(chǎng)景 | 性能評(píng)價(jià) | 學(xué)習(xí)曲線 |
|---|---|---|---|---|---|
| 手動(dòng)映射 | 高性能、簡(jiǎn)單明了 | 可維護(hù)性差,代碼冗余 | 簡(jiǎn)單對(duì)象轉(zhuǎn)換,性能關(guān)鍵場(chǎng)景 | ????? | ? |
| Builder模式 | 可讀性好,易擴(kuò)展 | 增加代碼量,需理解設(shè)計(jì)模式 | 對(duì)象屬性較多,需靈活配置 | ???? | ?? |
| 工具類(lèi)輔助映射 | 增強(qiáng)復(fù)用性,集中管理 | 可能導(dǎo)致工具類(lèi)膨脹,需手動(dòng)維護(hù) | 多處使用同樣映射邏輯 | ???? | ?? |
| MapStruct | 性能優(yōu)越,類(lèi)型安全 | 需要學(xué)習(xí)和配置,額外依賴(lài) | 復(fù)雜對(duì)象映射,性能要求高 | ????? | ??? |
| Spring BeanUtils | 快速開(kāi)發(fā),簡(jiǎn)單易用 | 性能較低,靈活性有限 | 快速原型開(kāi)發(fā),簡(jiǎn)單對(duì)象轉(zhuǎn)換 | ??? | ? |
| Dozer框架 | 功能強(qiáng)大,支持復(fù)雜映射 | 性能較低,學(xué)習(xí)成本高 | 靈活的映射配置,已有Dozer使用 | ?? | ??? |
| ModelMapper | 智能映射,簡(jiǎn)單易用 | 性能中等,可能需手動(dòng)調(diào)整 | 結(jié)構(gòu)相似對(duì)象,快速實(shí)現(xiàn)轉(zhuǎn)換 | ??? | ?? |
| 反射機(jī)制 | 高度靈活,無(wú)需額外依賴(lài) | 性能差,復(fù)雜性高 | 需要?jiǎng)討B(tài)處理屬性的特殊場(chǎng)景 | ? | ??? |
1. 手動(dòng)映射(Manual Mapping)
手動(dòng)映射是最直接的方式,通過(guò)手動(dòng)設(shè)置每個(gè)屬性來(lái)完成對(duì)象轉(zhuǎn)換。這種方式簡(jiǎn)單明了,適合于屬性較少的對(duì)象。
TargetObject target = new TargetObject(); target.setPropertyA(source.getPropertyA()); target.setPropertyB(source.getPropertyB()); // ...
2. Builder模式
Builder模式提供了一種流式API來(lái)創(chuàng)建對(duì)象,增強(qiáng)了代碼的可讀性和可維護(hù)性。
TargetObject target = TargetObject.builder()
.propertyA(source.getPropertyA())
.propertyB(source.getPropertyB())
.build();3. 工具類(lèi)輔助映射
通過(guò)創(chuàng)建專(zhuān)門(mén)的工具類(lèi)來(lái)封裝對(duì)象轉(zhuǎn)換邏輯,增強(qiáng)了代碼的復(fù)用性。
public class ObjectMapper {
public static TargetObject map(SourceObject source) {
TargetObject target = new TargetObject();
target.setPropertyA(source.getPropertyA());
target.setPropertyB(source.getPropertyB());
return target;
}
}4. 使用MapStruct框架
MapStruct是一個(gè)代碼生成器,可以在編譯時(shí)生成類(lèi)型安全的映射代碼,適合于復(fù)雜對(duì)象映射。
@Mapper
public interface ObjectMapper {
ObjectMapper INSTANCE = Mappers.getMapper(ObjectMapper.class);
@Mapping(source = "propertyA", target = "propertyA")
@Mapping(source = "propertyB", target = "propertyB")
TargetObject map(SourceObject source);
}5. 使用Spring BeanUtils/CopyProperties
Spring提供了BeanUtils工具類(lèi),可以快速進(jìn)行對(duì)象屬性復(fù)制,適用于快速開(kāi)發(fā)場(chǎng)景。
TargetObject target = new TargetObject(); BeanUtils.copyProperties(source, target);
6. 使用Dozer框架
Dozer是一款開(kāi)源的Java Bean到Java Bean的映射器,支持復(fù)雜的映射需求。
Mapper mapper = new DozerBeanMapper(); TargetObject target = mapper.map(source, TargetObject.class);
7. 使用ModelMapper
ModelMapper是一個(gè)智能的對(duì)象映射工具,適合復(fù)雜對(duì)象的自動(dòng)映射。
ModelMapper modelMapper = new ModelMapper(); TargetObject target = modelMapper.map(source, TargetObject.class);
8. 使用反射機(jī)制
通過(guò)Java反射機(jī)制可以動(dòng)態(tài)實(shí)現(xiàn)對(duì)象轉(zhuǎn)換,雖然靈活但性能較差。
Field[] fields = source.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object value = field.get(source);
Field targetField = target.getClass().getDeclaredField(field.getName());
targetField.setAccessible(true);
targetField.set(target, value);
}選擇建議
- 簡(jiǎn)單場(chǎng)景:手動(dòng)映射或Builder模式。
- 復(fù)雜場(chǎng)景:使用MapStruct或ModelMapper。
- 快速開(kāi)發(fā):Spring BeanUtils。
- 高性能要求:手動(dòng)映射或MapStruct。
- 靈活性要求高:反射機(jī)制。
性能從高到低排序如下:
手動(dòng)映射 > MapStruct > ModelMapper > Dozer > BeanUtils > 反射 > JSON序列化
可維護(hù)性對(duì)比
可維護(hù)性從高到低排序如下:
MapStruct > 手動(dòng)映射 > ModelMapper > Dozer > BeanUtils > 反射 > JSON序列化
使用建議
- 對(duì)于簡(jiǎn)單的DTO轉(zhuǎn)換,推薦使用手動(dòng)映射或Builder模式。
- 對(duì)于復(fù)雜的對(duì)象映射,推薦使用MapStruct。
- 對(duì)于快速開(kāi)發(fā)場(chǎng)景,可以使用Spring BeanUtils。
- 盡量避免使用JSON序列化/反序列化進(jìn)行對(duì)象轉(zhuǎn)換。
選擇建議
- 小型項(xiàng)目或簡(jiǎn)單對(duì)象:手動(dòng)映射或Spring BeanUtils。
- 大型項(xiàng)目或復(fù)雜對(duì)象轉(zhuǎn)換:MapStruct。
- 需要快速出結(jié)果:Spring BeanUtils或ModelMapper。
- 高度靈活的需求:反射機(jī)制(謹(jǐn)慎使用)。
每種方式都有其適用場(chǎng)景,開(kāi)發(fā)者需要根據(jù)具體需求選擇最合適的實(shí)現(xiàn)方式。希望這篇文章能幫助您在項(xiàng)目中做出更好的選擇。
到此這篇關(guān)于Java對(duì)象轉(zhuǎn)換的多種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Java對(duì)象轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java實(shí)現(xiàn)MapStruct對(duì)象轉(zhuǎn)換的示例代碼
- Java如何將任意類(lèi)型的Object對(duì)象轉(zhuǎn)換為相應(yīng)的實(shí)體對(duì)象
- Java中如何使用Gson將對(duì)象轉(zhuǎn)換為JSON字符串
- 如何將Java對(duì)象轉(zhuǎn)換成JSON
- Java?MapStruct優(yōu)雅地實(shí)現(xiàn)對(duì)象轉(zhuǎn)換
- java String類(lèi)型對(duì)象轉(zhuǎn)換為自定義類(lèi)型對(duì)象的實(shí)現(xiàn)
- Java中常見(jiàn)的對(duì)象轉(zhuǎn)換工具
- 如何將Java對(duì)象轉(zhuǎn)換為JSON實(shí)例詳解
- 使用spring boot開(kāi)發(fā)時(shí)java對(duì)象和Json對(duì)象轉(zhuǎn)換的問(wèn)題
- java對(duì)象轉(zhuǎn)換String類(lèi)型的三種方法
相關(guān)文章
eclipse+myeclipse 環(huán)境配置方法
eclipse+myeclipse配置環(huán)境2009-07-07
詳解spring-boot actuator(監(jiān)控)配置和使用
本篇文章主要介紹了spring-boot actuator(監(jiān)控)配置和使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
Spring\SpringBoot配置連接數(shù)據(jù)庫(kù)的方法
最近在學(xué)習(xí)SpringBoot,第一步就是要配置數(shù)據(jù)庫(kù),本文詳細(xì)的介紹了Spring\SpringBoot配置連接數(shù)據(jù)庫(kù)的方法,有需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06
Java實(shí)現(xiàn)解壓zip壓縮包的兩種方法(支持多層級(jí))
壓縮文件在生活中經(jīng)常能用到,在Java中提供了壓縮和解壓縮文件的功能,本文主要介紹了Java實(shí)現(xiàn)解壓zip壓縮包的兩種方法(支持多層級(jí)),感興趣的可以了解一下2024-03-03
詳解maven中profiles使用實(shí)現(xiàn)
本文主要介紹了maven中profiles使用實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Java8 forEach常用場(chǎng)景代碼實(shí)例
這篇文章主要介紹了Java8 forEach常用場(chǎng)景代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Spring之ShutDown?Hook死鎖現(xiàn)象解讀
這篇文章主要介紹了Spring之ShutDown?Hook死鎖現(xiàn)象解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04

