导读:本期聚焦于小伙伴创作的《Java中跨包同名DTO列表如何进行类型转换与映射》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java中跨包同名DTO列表如何进行类型转换与映射》有用,将其分享出去将是对创作者最好的鼓励。

在Java项目开发中,随着业务模块拆分越来越细,不同模块可能会定义结构相似但包路径不同的同名DTO,当需要把其中一个包下的DTO列表转换为另一个包下的同名DTO列表时,就需要处理类型转换与映射的问题。这种场景在微服务间数据传递、模块间解耦交互中非常常见,处理不当会导致大量重复代码或者运行时类型转换错误。

Java中跨包同名DTO列表如何进行类型转换与映射

场景说明

假设我们有两个不同包下的同名DTO,结构完全一致,只是包路径不同:

com.example.module_a.dto下的UserDTO:

public class UserDTO {
    private Long id;
    private String name;
    private Integer age;

    // 省略getter、setter方法
}

com.example.module_b.dto下的UserDTO:

public class UserDTO {
    private Long id;
    private String name;
    private Integer age;

    // 省略getter、setter方法
}

现在我们需要将com.example.module_a.dto.UserDTO的列表转换为com.example.module_b.dto.UserDTO的列表,下面介绍几种实现方式。

方案一:手动字段映射

手动映射是最基础的方式,逐个获取源对象的字段值,设置到目标对象中,适合字段数量少、转换逻辑简单的场景。

import com.example.module_a.dto.UserDTO as ModuleAUserDTO;
import com.example.module_b.dto.UserDTO as ModuleBUserDTO;
import java.util.ArrayList;
import java.util.List;

public class DTOConverter {
    public static List<ModuleBUserDTO> convertListManual(List<ModuleAUserDTO> sourceList) {
        if (sourceList == null) {
            return null;
        }
        List<ModuleBUserDTO> targetList = new ArrayList<>();
        for (ModuleAUserDTO source : sourceList) {
            ModuleBUserDTO target = new ModuleBUserDTO();
            target.setId(source.getId());
            target.setName(source.getName());
            target.setAge(source.getAge());
            targetList.add(target);
        }
        return targetList;
    }
}

这种方式的优点是逻辑清晰,没有额外依赖,缺点是当字段数量多或者需要转换的DTO类型多时,代码冗余度高,后期如果DTO字段变更,需要同步修改所有转换代码,维护成本高。

方案二:使用Spring BeanUtils批量转换

Spring框架提供的BeanUtils工具类可以自动复制同名同类型的字段,适合字段名和类型完全一致的场景,不需要手动逐个赋值。

import com.example.module_a.dto.UserDTO as ModuleAUserDTO;
import com.example.module_b.dto.UserDTO as ModuleBUserDTO;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;

public class DTOConverter {
    public static List<ModuleBUserDTO> convertListByBeanUtils(List<ModuleAUserDTO> sourceList) {
        if (sourceList == null) {
            return null;
        }
        List<ModuleBUserDTO> targetList = new ArrayList<>();
        for (ModuleAUserDTO source : sourceList) {
            ModuleBUserDTO target = new ModuleBUserDTO();
            BeanUtils.copyProperties(source, target);
            targetList.add(target);
        }
        return targetList;
    }
}

这种方式的优点是代码简洁,减少重复劳动,缺点是无法处理字段名不同、类型不同或者需要自定义转换逻辑的场景,而且反射调用会有一定的性能损耗,不过在普通业务场景下损耗可以忽略。

方案三:使用MapStruct框架映射

MapStruct是一个基于注解的代码生成器,在编译期生成类型转换的实现代码,性能接近手动映射,同时支持自定义转换逻辑,适合复杂转换场景。

首先添加Maven依赖:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.5.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.5.Final</version>
    <scope>provided</scope>
</dependency>

然后定义转换接口:

import com.example.module_a.dto.UserDTO as ModuleAUserDTO;
import com.example.module_b.dto.UserDTO as ModuleBUserDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;

@Mapper
public interface UserDTOMapper {
    UserDTOMapper INSTANCE = Mappers.getMapper(UserDTOMapper.class);

    ModuleBUserDTO toModuleBUserDTO(ModuleAUserDTO source);

    List<ModuleBUserDTO> toModuleBUserDTOList(List<ModuleAUserDTO> sourceList);
}

使用时直接调用接口方法即可:

import com.example.module_a.dto.UserDTO as ModuleAUserDTO;
import com.example.module_b.dto.UserDTO as ModuleBUserDTO;
import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<ModuleAUserDTO> sourceList = Arrays.asList(
            new ModuleAUserDTO(1L, "张三", 20),
            new ModuleAUserDTO(2L, "李四", 22)
        );
        List<ModuleBUserDTO> targetList = UserDTOMapper.INSTANCE.toModuleBUserDTOList(sourceList);
        System.out.println(targetList);
    }
}

MapStruct的优点是编译期生成代码,性能高,支持自定义字段映射、类型转换,适合中大型项目的复杂转换需求,缺点是需要额外引入依赖,学习成本比前两种方案稍高。

方案对比与选择建议

方案优点缺点适用场景
手动映射无依赖、逻辑清晰代码冗余、维护成本高字段少、转换逻辑简单的临时场景
Spring BeanUtils代码简洁、无复杂依赖不支持自定义转换、反射有性能损耗字段完全一致、无自定义逻辑的普通业务场景
MapStruct性能高、支持自定义逻辑、维护方便需要引入额外依赖中大型项目、复杂转换场景、多类型转换需求

在实际开发中,我们可以根据项目规模、转换复杂度选择合适的方案,如果项目已经引入了Spring框架,优先选择Spring BeanUtils处理简单场景;如果是长期维护的中大型项目,推荐使用MapStruct来统一处理所有DTO转换需求,提升代码的可维护性。

JavaDTO类型转换对象映射跨包同名修改时间:2026-07-14 10:57:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。