兄弟们,今天咱来聊个让小寡妇们听了都直摇头的问题:滥用 != null
判空。别觉得这是小菜一碟,多少大佬程序员踩过这坑。每次 code review,看着一堆 != null
,我这暴脾气就上来了。这种码农习惯啊,咱得治!
为啥滥用 != null
是个坑
你还记得你第一次写 Java 代码吗?那时候,每次调用一个方法,你都会写上 if (something != null)
。老实说,这习惯就跟小时候写作文一样,开头必写“一个风和日丽的早晨”,死板得很。滥用 != null
,不光让代码看着冗长,还容易藏 BUG。想想你那几十行的 if-else 判空,谁能一眼看出问题?
Optional 来拯救世界
Java 8 给咱们带来了个神器——Optional
。啥意思呢?就是咱们可以用 Optional
来包装那些可能为 null 的对象,不再需要满世界写判空。
举个栗子:
// 没用 Optional 前的老方法
public String getName(Person person) {
if (person != null) {
return person.getName();
} else {
return "Unknown";
}
}
换成 Optional 之后:
import java.util.Optional;
public String getName(Person person) {
return Optional.ofNullable(person)
.map(Person::getName)
.orElse("Unknown");
}
瞅瞅,是不是简洁多了?
少返回 null,多抛异常
有时候,咱们的确需要处理异常情况。很多初中级程序员喜欢返回 null 来表示异常情况。这其实是个坏习惯,应该多抛异常,少返回 null。为啥?因为 null 会让你的代码变得更脆弱,增加 NPE(NullPointerException)风险。
再举个栗子:
// 不推荐的返回 null 方式
public Person findPersonById(int id) {
if (id < 0) {
return null;
}
// 查找逻辑
}
// 调用时需要判空
Person person = findPersonById(-1);
if (person != null) {
// 处理 person
}
推荐的方式是抛异常**:
// 推荐的抛异常方式
public Person findPersonById(int id) {
if (id < 0) {
throw new IllegalArgumentException("ID 不能小于 0");
}
// 查找逻辑
}
// 调用时处理异常
try {
Person person = findPersonById(-1);
// 处理 person
} catch (IllegalArgumentException e) {
// 处理异常
}
保护自己,别过度判空
有些程序员,不知道是不是被 NPE 吓坏了,写代码像在防贼一样,到处加判空。这样做不仅浪费时间,还让代码臃肿。关键是,你不信任你的代码,谁还敢信任?
例如:
// 滥用判空
if (obj != null && obj.getField() != null && obj.getField().getSubField() != null) {
// 逻辑处理
}
其实,你可以通过设计让代码更健壮,减少这些判空。例如使用工厂模式确保对象不为 null,或者用 Optional 链式调用。
// 使用 Optional
Optional.ofNullable(obj)
.map(Object::getField)
.map(Field::getSubField)
.ifPresent(subField -> {
// 逻辑处理
});
咱们再来举两个例子
深入理解一下为什么要减少 != null
判空,并学会用 Optional
和抛异常来处理特殊情况。
例子 1:处理用户输入
假设我们有个方法要处理用户输入,如果用户输入为空,我们返回一个默认值。传统方法可能会这样写:
// 传统方法,判空处理
public String processInput(String input) {
if (input != null) {
return input.trim();
} else {
return "default";
}
}
使用 Optional
改写:
import java.util.Optional;
public String processInput(String input) {
return Optional.ofNullable(input)
.map(String::trim)
.orElse("default");
}
瞧瞧,这一改,代码瞬间清爽了许多,不再需要繁琐的判空操作。
例子 2:获取配置参数
我们再来看一个获取配置参数的例子。通常情况下,我们会从配置文件中读取参数,如果参数不存在,我们可能会返回 null
,然后在调用处进行判空处理:
// 传统方法,返回 null 并判空
public String getConfig(String key) {
String value = configMap.get(key);
if (value != null) {
return value;
} else {
return null;
}
}
public void useConfig() {
String value = getConfig("someKey");
if (value != null) {
// 使用配置
} else {
// 使用默认值
}
}
改用 Optional
:
import java.util.Optional;
public Optional<String> getConfig(String key) {
return Optional.ofNullable(configMap.get(key));
}
public void useConfig() {
String value = getConfig("someKey")
.orElse("defaultValue");
// 使用配置或默认值
}
用 Optional
后,代码变得更加简洁,而且一眼就能看出逻辑,不再需要在每个调用处判空。
通过这两个例子,咱们可以看到,使用 Optional
能让代码更加简洁明了,减少了不必要的判空操作。而在一些特定场景下,抛出异常也能避免 null 值带来的潜在风险。
总结一波
兄弟们,今天咱们聊了这么多,不就是想说一件事儿:别再滥用 != null
判空了!这习惯就像穿着秋裤跳舞,碍手碍脚还丢人。
回顾一下咱们聊的几个要点:
Optional 的妙用:Java 8 给我们带来了 Optional
,用它包装可能为 null 的对象,减少判空操作,让代码更简洁明了。
多抛异常,少返回 null:当遇到异常情况时,返回 null 不是好习惯。应该抛出适当的异常,这样可以提高代码的健壮性,减少潜在的 NPE 风险。
设计优雅代码,减少判空:过度判空不仅让代码臃肿,还容易埋下 BUG。通过设计模式和 Optional
,可以让代码更健壮,减少不必要的判空操作。
最后,写代码也得讲究个艺术感。少点 != null
的啰嗦,多点 Optional
的优雅;少点判空的紧张,多点设计的从容。
已收录于,我的技术网站:ddkk.com 里面有,500套技术系列教程、1万+道,面试八股文、BAT面试真题、简历模版,工作经验分享、架构师成长之路,等等什么都有,欢迎收藏和转发。