Java可变对象导致空指针异常
Posted
技术标签:
【中文标题】Java可变对象导致空指针异常【英文标题】:Java mutable object to causing nullpointer exception 【发布时间】:2021-11-25 11:09:50 【问题描述】:我有以下 DTO,我将对象传递给 ArrayList
s 以防止更改对象并将 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);
那么,有没有更好的方法来解决没有空检查的问题?
【问题讨论】:
在调用构造函数之前,可以检查它们是否不为空。但这很好。它不必总是美丽的。 【参考方案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::isNull
或Optional
)并返回预期结果:
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);
【讨论】:
以上是关于Java可变对象导致空指针异常的主要内容,如果未能解决你的问题,请参考以下文章
在 Activity 中调用 Fragment 方法会导致空指针异常
java空指针异常:java.lang.NullPointException
SpringBug记录 -- java.lang.NullPointerException在Spring单元测试中遇到的空指针异常及依赖注入异常总结