【小细节】Kotlin空指针安全的细节处理-toString&hashCode

53 阅读1分钟

发现

发现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());

运行上方代码,会发现程序直接报错,空指针异常了。

image.png

但是如果放在Kotlin中,相同的调用方式:

        val invalidJsonBytes = "invalid json".toByteArray()
        val json = Misc.safeParseJson(invalidJsonBytes)
        println(">>> " + json.hashCode())

运行代码,可以看到程序正常运行,且输出最终结果hashCode为0.

image (1).png

我们加一行判断,看下这个时候返回的对象是否为Null

        val invalidJsonBytes = "invalid json".toByteArray()
        val json = Misc.safeParseJson(invalidJsonBytes)
        println(">>> " + json.hashCode())

        if (json == null) {
            println("==> json is null")
        }

可以看到程序依然正常运行,并且确实也进入到了为null的判断逻辑中。

image (2).png

原因

Kotlin对于部分方法有制作扩展方法,比如对于hashCode,toString这类方法,都有定义扩展方法,扩展方法里有包含为空指针的情况。

image (3).png

image (4).png