声纳Qube:"Store a copy of "产品过敏原信息" "



我有以下DTO:

@Data
@RequiredArgsConstructor
public class MenuItemExpandedDTO {
private UUID uuid;
private List<ModifierGroupDTO> modifierGroupDtoList;
private List<AllergenInfo> allergenInfoList;
public MenuItemExpandedDTO(
PropertiesDTO propertiesDto,
List<ModifierGroupDTO> modifierGroupDtoList,
List<AllergenInfo> allergenInfoList
) {
this.uuid = propertiesDto.getUuid();
this.modifierGroupDtoList = modifierGroupDtoList;
this.allergenInfoList = allergenInfoList;
}
}

在SonarQube分析中,我得到了一个由allergenInfoList引起的漏洞,如所述

消息:存储allergeninfolist的副本

所以,我不确定问题是什么,但在修复此错误之前,我想知道该代码有什么问题?在某些页面中,建议初始化列表,例如private List<AllergenInfo> allergenInfoList = Collections.emptyList()。但这不是我在我的项目中遵循的方式。那么,这段代码的问题是什么呢?

SonarQube告诉你在构造函数中接收List时要小心。为什么?因为调用者持有对该List的引用,并且如果它不是不可变的,它可以对它执行以下操作:

  1. 通过添加或删除元素来改变List的内容,实际影响MenuItemExpandedDTO
  2. 更改List中包含的对象,如果它们不是不可变的。这意味着List中的AllergenInfo对象可以被更改,从而影响MenuItemExpandedDTO对象。

To tackle 1。,您可以按照SonarQube的建议简单地存储List的副本:

public MenuItemExpandedDTO(
PropertiesDTO propertiesDto,
List<ModifierGroupDTO> modifierGroupDtoList,
List<AllergenInfo> allergenInfoList
) {
this.uuid = propertiesDto.getUuid();
this.modifierGroupDtoList = new ArrayList<>(modifierGroupDtoList);
this.allergenInfoList = new ArrayList<>(allergenInfoList);
}
}

处理2。更棘手、更简单、更可靠的解决方案是使用不可变对象。您可以在https://www.baeldung.com/java-immutable-object上阅读更多关于这方面的内容,以及如何设计您的类以获得不可变对象。

public class MenuItemExpandedDTO {
private final UUID uuid;
private final List<ModifierGroupDTO> modifierGroupDtoList;
private final List<AllergenInfo> allergenInfoList;
public MenuItemExpandedDTO(PropertiesDTO propertiesDto,
List<ModifierGroupDTO> modifierGroupDtoList,
List<AllergenInfo> allergenInfoList) {
this.uuid = propertiesDto.getUuid();
this.modifierGroupDtoList = new ArrayList<>(modifierGroupDtoList);
this.allergenInfoList = new ArrayList<>(allergenInfoList);
}
public UUID getUuid() {
return UUID;
}
public List<ModifierGroupDTO> getModifierGroupDtoList() {
return new ArrayList<>(modifierGroupDtoList);
}
public List<AllergenInfo> getAllergenInfoList() {
return new ArrayList<>(allergenInfoList);
}
}

请记住,ModifierGroupDTOAllergenInfo也必须是不可变的,这样MenuItemExpandedDTO是100%不可变的。

最新更新