发现
发现Kotlin中调用java 方法时候,返回一个对象,这个对象可能会为Null。这个时候我们调用该对象的hashCode和toString方法,并不会报空指针异常,但是如果在java中去这么做则直接会抛出空指针异常。
实验
比如我存在下方的一个java方法:
class Misc
public static JSONObject safeParseJson(byte[] data) {
try {
return new JSONObject(new String(data));
} catch (Exception e) {
return null;
}
}
}
上边这个方法很简单对Android解析JSON字符串的方法做了一个catch异常保护,如果发现字符串不满足JSON格式就会catch异常返回Null。
我们如果在java中使用该方法时候,故意传一个不满足json格式的字符串,然后调用其hashCode方法:
byte[] invalidJsonBytes = "invalid json".getBytes();
JSONObject json = Misc.safeParseJson(invalidJsonBytes);
System.out.println(">>> " + json.hashCode());
运行上方代码,会发现程序直接报错,空指针异常了。
但是如果放在Kotlin中,相同的调用方式:
val invalidJsonBytes = "invalid json".toByteArray()
val json = Misc.safeParseJson(invalidJsonBytes)
println(">>> " + json.hashCode())
运行代码,可以看到程序正常运行,且输出最终结果hashCode为0.
我们加一行判断,看下这个时候返回的对象是否为Null
val invalidJsonBytes = "invalid json".toByteArray()
val json = Misc.safeParseJson(invalidJsonBytes)
println(">>> " + json.hashCode())
if (json == null) {
println("==> json is null")
}
可以看到程序依然正常运行,并且确实也进入到了为null的判断逻辑中。
原因
Kotlin对于部分方法有制作扩展方法,比如对于hashCode,toString这类方法,都有定义扩展方法,扩展方法里有包含为空指针的情况。