1. 正确使用 String类的 equals()方法 和 Object类的 equals() 方法
已知对象在前,未知对象在后。注意:已知对象不为 null
正确示例
public static void main(String[] args) {
String name = "sungm";
//name为已知对象且被赋予初始值不为空
if (name.equals(getOtherName())) {
//todo do something
System.out.println("todo do something");
}
}
private static String getOtherName() {
return "sungm";
}
错误示例
public static void main(String[] args) {
String name = "sungm";
//getOtherName()方法返回值为 null。抛出NPE
if (getOtherName().equals(name)) {
//todo do something
System.out.println("todo do something");
}
}
private static String getOtherName() {
return null;
}
2. 未知对象转String使用String.valueOf()方法
空对象调用 toString() 方法会抛出NPE,使用 String.valueOf() 替代
示例
public static void main(String[] args) {
//抛NPE
System.out.println(getPrice().toString());
//不抛NPE
System.out.println(String.valueOf(getPrice()));
}
private static BigDecimal getPrice() {
return null;
}
String.valueOf() 方法源码
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
3. 使用第三方类库或者自己封装的工具类
例如 Apache 的 StringUtils 类
Apache 的 StringUtils工具类部分源码
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
public static boolean isBlank(String str) {
int strLen;
if (str != null && (strLen = str.length()) != 0) {
for(int i = 0; i < strLen; ++i) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
return true;
} else {
return true;
}
}
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
Apache 中 StringUtils 中 isEmpty() 方法 和 isBlank() 方法的区别:
1: isEmpty() 方法:当Sting为null或者空("")时返回true
2: isBlank() 方法 :当Sting为null或者空("")或者空字符串(" ")时返回true
示例
public static void main(String[] args) {
String empty = null;
System.out.println(StringUtils.isEmpty(empty));
empty = "";
System.out.println(StringUtils.isEmpty(empty));
empty = " ";
System.out.println(StringUtils.isBlank(empty));
}
4. 避免自动拆箱可能抛出NPE
自动拆箱可能抛出NPE
//反例
public int function() {
return Integer对象;
}
5. 数据库查出的数据可能为null,做空判断
数据库非空字段可以加非空约束;对可能为空的字段做空判断、防止NPE。
6. 级联调用容易抛出NPE,建议使用Java 8 的 Optional类
例如 object.getMehtodA().getMethodB().getMethodC();很容易抛出NPE
7. 远程调用返回对象容易抛出NPE,建议做空判断
调用第三方接口等返回对象可能为空,建议对该对象操作之前做空判断。
8. 取Session中 的值之前做空判断
取Session的值之前对Session做空判断,对获取的Session值操作之前对Session值做空判断、避免NPE
9. 对集合的操作之前做空判断
取集合中的值之前对集合做空判断,对获取的集合值操作之前对集合值做空判断、避免NPE