【问题标题】:Java mutable object to causing nullpointer exceptionJava可变对象导致空指针异常
【发布时间】:2021-11-25 11:09:50
【问题描述】:

我有以下 DTO,我将对象传递给 ArrayLists 以防止更改对象并将 SonarQube 错误修复为 “消息:存储 allergenInfoList 的副本” 等。

public MenuItemDTO(
        PropertiesDTO propertiesDto,
        List<ModifierDTO> modifierDtoList,
        List<AllergenInfo> allergenInfoList
) {
    this.uuid = propertiesDto.getUuid();
    this.modifierDtoList = new ArrayList<>(modifierDtoList);
    this.allergenInfoList = new ArrayList<>(allergenInfoList);
  }
}

但是,这种方法需要空检查,它使我的代码丑陋,如下所示:

public MenuItemDTO(
        PropertiesDTO propertiesDto,
        List<ModifierDTO> modifierDtoList,
        List<AllergenInfo> allergenInfoList
) {
    this.uuid = propertiesDto.getUuid();
    if (modifierDtoList != null) {
        this.modifierDtoList = new ArrayList<>(modifierDtoList);
    }
    if (allergenInfoList != null) {
        this.allergenInfoList = new ArrayList<>(allergenInfoList);
    }
}

那么,有没有更好的方法来解决没有空检查的问题?

【问题讨论】:

  • 在调用构造函数之前,可以检查它们是否不为空。但这很好。它不必总是美丽的。

标签: java spring sonarqube sonarqube-scan mutable


【解决方案1】:

这是一个解决将空列表作为输入参数的可能性的解决方案,但它需要比简单的空检查更多的代码

创建一个类似的方法:

private <T> List<T> copyList(List<T> list) {
    return Optional.ofNullable(list)
            .map(List::stream)
            .orElseGet(Stream::empty)
            .collect(Collectors.toList());
}

只需使用类似的方法,并在此方法中只执行一次 if null 检查:

private <T> List<T> copyList(List<T> list) {
    if (list != null) {
        return new ArrayList<>(list);
    }
    return new ArrayList<>();
}

并在你的构造函数上使用这个方法,这样看起来更优雅:

public MenuItemDTO(
        PropertiesDTO propertiesDto,
        List<ModifierDTO> modifierDtoList,
        List<AllergenInfo> allergenInfoList
) {
    this.uuid = propertiesDto.getUuid();
    this.modifierDtoList = copyList(modifierDtoList);
    this.allergenInfoList = copyList(allergenInfoList);
   
}

【讨论】:

  • 为什么使用原始List ?它可以很容易地泛化
【解决方案2】:

一种更时尚的解决方案,可能避免创建流和收集元素的需要:

例如检查这个:

private <T> List<T> copyList(List<T> list) {
    return Optional.ofNullable(list)
        .map(ArrayList::new)
        .orElseGet(ArrayList::new);
}

这有效地检查传入列表是否为null,继续复制它。否则,它只会创建一个新的空列表。除此之外,它还负责泛型和类型。

【讨论】:

    【解决方案3】:

    最好实现一个实用程序/辅助方法来处理空检查(直接使用Objects::isNullOptional)并返回预期结果:

    public class Util {
        public static List<?> copyOrNull(List<?> src) {
            return null == src ? src : new ArrayList<>(src);
        }
    
        public static List<?> copyOrEmpty(List<?> src) {
            return null == src ? Collections.emptyList() : new ArrayList<>(src);
        }
    }
    

    然后根据需要更新 DTO 代码:

    
    public MenuItemDTO(
            PropertiesDTO propertiesDto,
            List<ModifierDTO> modifierDtoList,
            List<AllergenInfo> allergenInfoList
    ) {
        this.uuid = propertiesDto.getUuid();
        this.modifierDtoList = Util.copyOrNull(modifierDtoList);
        this.allergenInfoList = Util.copyOrEmpty(allergenInfoList);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 2015-09-12
      相关资源
      最近更新 更多