如何将不同包下同名DTO的List对象相互赋值?
场景
我有两个同名的DTO类(CobrandedCardDto),属性完全相同但位于不同包下:
com.loyalty.marketplace.offers.member.management.outbound.dtocom.loyalty.marketplace.outbound.dto
CobrandedCardDto的属性如下:
private String partnerCode; private String bankId; private String status; private String cardType;
我从com.loyalty.marketplace.outbound包的服务中获取到List<CobrandedCardDto>,需要将其赋值给com.loyalty.marketplace.offers.member.management.outbound包下的List<CobrandedCardDto>,期望执行类似如下代码:
memberDetails.setCobrandedCardDetails(MemberAccountInfoDto.getCobrandedCardDetails());
其中cobrandedCardDetails是List<CobrandedCardDto>类型的变量。
问题
我无法完成该赋值操作,出现如下错误,请问该如何解决?
方法 setCobrandedCardDetails(java.util.List<com.loyalty.marketplace.offers.member.management.outbound.dto.CobrandedCardDto>) 在类型 GetMemberResponse 中不适用于参数 (java.util.List<com.loyalty.marketplace.outbound.dto.CobrandedCardDto>)
解决方案
即使两个类属性完全一致,Java也会将它们视为不同的类型,因此直接赋值List会触发类型不匹配错误。以下是几种可行的解决方式:
1. 手动逐个转换对象
遍历源List,将每个源DTO的属性逐一赋值给目标DTO,再收集为目标类型的List:
// 获取源列表 List<com.loyalty.marketplace.outbound.dto.CobrandedCardDto> sourceList = MemberAccountInfoDto.getCobrandedCardDetails(); // 初始化目标列表 List<com.loyalty.marketplace.offers.member.management.outbound.dto.CobrandedCardDto> targetList = new ArrayList<>(); for (com.loyalty.marketplace.outbound.dto.CobrandedCardDto sourceDto : sourceList) { com.loyalty.marketplace.offers.member.management.outbound.dto.CobrandedCardDto targetDto = new com.loyalty.marketplace.offers.member.management.outbound.dto.CobrandedCardDto(); targetDto.setPartnerCode(sourceDto.getPartnerCode()); targetDto.setBankId(sourceDto.getBankId()); targetDto.setStatus(sourceDto.getStatus()); targetDto.setCardType(sourceDto.getCardType()); targetList.add(targetDto); } // 完成赋值 memberDetails.setCobrandedCardDetails(targetList);
2. 使用Bean映射工具简化转换
如果项目中引入了MapStruct、ModelMapper这类映射工具,可以通过定义映射规则自动完成转换,减少手动代码:
以MapStruct为例,先定义映射接口:
@Mapper public interface CobrandedCardMapper { CobrandedCardMapper INSTANCE = Mappers.getMapper(CobrandedCardMapper.class); // 单个对象转换 com.loyalty.marketplace.offers.member.management.outbound.dto.CobrandedCardDto toTargetDto(com.loyalty.marketplace.outbound.dto.CobrandedCardDto sourceDto); // 列表批量转换 List<com.loyalty.marketplace.offers.member.management.outbound.dto.CobrandedCardDto> toTargetList(List<com.loyalty.marketplace.outbound.dto.CobrandedCardDto> sourceList); }
然后直接调用工具完成转换:
List<com.loyalty.marketplace.outbound.dto.CobrandedCardDto> sourceList = MemberAccountInfoDto.getCobrandedCardDetails(); List<com.loyalty.marketplace.offers.member.management.outbound.dto.CobrandedCardDto> targetList = CobrandedCardMapper.INSTANCE.toTargetList(sourceList); memberDetails.setCobrandedCardDetails(targetList);
3. 重构代码(推荐方案)
既然两个DTO属性完全一致,建议将通用的CobrandedCardDto迁移到公共包下,让两个模块统一引用这个公共类,从根源上避免类型不匹配的问题,同时减少重复代码的维护成本。
内容的提问来源于stack exchange,提问作者Ayub Jamal

