SonarQube:"Store a copy of "productAllergenInfos“”
SonarQube: "Store a copy of "productAllergenInfos""
我有以下 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
s 时要小心。为什么?因为调用者持有对该 List
的引用,如果它不是不可变的,它可以对其执行以下操作:
- 通过向其中添加或删除元素来更改
List
内容,实际上会影响您的 MenuItemExpandedDTO
。
- 更改
List
中包含的对象(如果它们不是不可变的)。这意味着可以更改 List
中的 AllergenInfo
个对象,影响您的 MenuItemExpandedDTO
个对象。
要解决 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);
}
}
请记住,ModifierGroupDTO
和 AllergenInfo
也必须是不可变的,因此 MenuItemExpandedDTO
是 100% 不可变的。
我有以下 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
s 时要小心。为什么?因为调用者持有对该 List
的引用,如果它不是不可变的,它可以对其执行以下操作:
- 通过向其中添加或删除元素来更改
List
内容,实际上会影响您的MenuItemExpandedDTO
。 - 更改
List
中包含的对象(如果它们不是不可变的)。这意味着可以更改List
中的AllergenInfo
个对象,影响您的MenuItemExpandedDTO
个对象。
要解决 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);
}
}
请记住,ModifierGroupDTO
和 AllergenInfo
也必须是不可变的,因此 MenuItemExpandedDTO
是 100% 不可变的。