打开 NullPointerException
源码 开头就写明出现 NullPointerException
的原因:
通俗的讲,现在有一个未拆苹果max盒子(一个对象),但是盒子里并没有苹果手机(没有初始化分配内存,获得引用)
如果你从商场买回家,然后闲鱼上转卖,然后买家继续转卖(方法调用),
转卖了十几波,中间一直没人打开,第15个人,正好是刘德华,刘德华买到手之后,突然打开想看看手机什么样(使用对象),一看盒子里面是空的,什么都没有,然后刘德华就生气了,这个生气就是空指针异常.
假如这个手机盒一直没人打开,只是在流转,那么就不存在空指针异常,只要打开,使用,修改就会空指针异常.
那么什么时候你会打开盒子呢
Invoking a method from a null object.
调用空对象的方法
刘德华: “哎呀,苹果手机听说好像可以上网,不知道是不是真的,我用手上这台试试”.
那他必须要拆开盒子看手机咯,一看别说打电话(使用对象的方法)了,连手机(对象为空)都没有.
直接生气,爆发空指针异常.
Accessing or modifying a null object’s field.
获取或者修改空对象的字段
刘德华: 哎呀,苹果原装耳机我选择自己留下,我换个淘宝50的放里边(修改对象内容),没人会知道,嘿嘿.拆开盒子,空的(对象为空)!! 直接生气,爆发空指针异常.
Taking the length of null, as if it were an array.
获取一个空数组的长度
刘德华: “老板,帮我用尺子量下我新买的苹果手机长度(获取空数组长度)”
老板小心翼翼的接过这台隐形的手机.过了半天告诉大明星 “不好意思啊,华仔,手机长度是没有!!”
“什么没有,再短也要有个长度吧,连0.00000000001纳米都没有??”
“真的没有,比(1-∞)都不如,是根本没有”
华仔发飙"你店别开了".
爆发空指针异常,老板被打.
Accessing or modifying the slots of null object, as if it were an array.
获得或者修改空数组的一个位置上的内容
刘德华: "老板娘,帮我把我这台手机侧面的 0.618黄金比例刻一个 华仔帅帅
"(修改空数组上某位置内容).
老板娘 瞅了瞅这台手机隐形的侧面(空数组) : “… emmm 人家做不到”
刘德华: “算了,天天发飙累了,儿子你上”.
刘德虎发飙,爆发空指针异常.老板娘被打.
Throwing null, as if it were a Throwable value.
TODO 不太明白,是指主动抛出吗
When you try to synchronize over a null object.
代码说话
synchronized(obj1)
{
obj1 = null;
}
synchronized(obj1)
{
do something
}
示意一下:
public class NullExample {
public static void print(String s, Exception e) {
System.out.println(s + " " + e.getClass());
}
public void useNullObjectMethod(User user) {
try {
user.getName();
} catch (NullPointerException e) {
print("useNullObjectMethod", e);
}
}
public void modifyNullObjectProperty(User user) {
try {
user.name = "滴滴滴";
} catch (NullPointerException e) {
print("modifyNullObjectProperty", e);
}
}
public void getNullArrayLength(List list) {
try {
int size = list.size();
} catch (NullPointerException e) {
print("getNullArrayLength", e);
}
}
public void modifyNullArrayValue(List list) {
try {
list.remove(2);
} catch (NullPointerException e) {
print("modifyNullArrayValue", e);
}
}
}
public class ApplicationTests {
private static NullExample example = new NullExample();
private static User userNull = null;
private static List listNull = null;
@Test
public void useNullObjectMethodTest() {
example.useNullObjectMethod(userNull);
}
@Test
public void modifyNullObjectPropertyTest() {
example.modifyNullObjectProperty(userNull);
}
@Test
public void getNullArrayLengthTest() {
example.getNullArrayLength(listNull);
}
@Test
public void modifyNullArrayValueTest() {
example.modifyNullArrayValue(listNull);
}
}
如果空指针异常出现,最好还是手动处理、调用前判断是否为空或者返回空字符串,空集合…
return Optional.ofNullable(user).map(name -> user.getName()).orElse("空空空");
return Optional.ofNullable(user).map(name -> user.getName())
.orElseThrow(IllegalAccessException::new);
使用代码检查工具,可以有效规避空指针异常