記錄一次Java Convert Kotlin造成的空指針異常

不知道大家在使用Kotlin進(jìn)行編碼的時候,有沒有直接使用AS的Code -> Convert Java File 2 Kotlin File這個功能,此功能在日常使用中還是比較實(shí)用的,可以幫助我們將老的Java或者復(fù)制的Java代碼(??)一鍵轉(zhuǎn)換成Kotlin代碼,最近在使用此功能的時候竟然遇到了空指針的Crash,在此記錄一下,順便也給大家做個預(yù)警。

起因

在工程中引入了三方的SDK,此SDK使用Java編碼,我們需要實(shí)現(xiàn)它的一個回調(diào)方法做一下異常處理,SDK具體方法就不貼出來了,下面模擬一下他們的回調(diào)

public class Test {

    // 定義回調(diào)接口,其中error用來處理異常情況,參數(shù)為Exception對象
    public interface TestCallback {
        void test();

        void error(Exception e);
    }

    // 傳入回調(diào)并直接模擬調(diào)用它的方法
    public void setTest(TestCallback testCallback) {
        testCallback.test();
        testCallback.error(new Exception("test"));
    }
}

模擬了它們的回調(diào)接口,然后在setTest(callback)中直接調(diào)用接口方法,這里先看一下這個error的接口方法,它的參數(shù)exception并沒有使用可空(@Nullable)或者非空(@NonNull)注解來定義,默認(rèn)就是可空類型。

然后我們直接模擬調(diào)用下看看具體效果,先用Java代碼來調(diào)用

public class Java2Kt {

    private final Test testCallback = new Test();

    public void test() {
        testCallback.setTest(new Test.TestCallback() {
            @Override
            public void test() {
                Log.d("taonce", "Java2Kt test");
            }

            @Override
            public void error(Exception e) {
                if (e != null) {
                    Log.d("taonce", "Java2Kt error " + e.getMessage());
                }
            }
        });
    }
}

# 
Java2Kt test
Java2Kt error java.lang.Exception: custom exception

這樣就沒得毛病,可以正確調(diào)用并輸出日志,然后我們改一下setTest(callback)方法,再額外添加一行

public void setTest(TestCallback testCallback) {
    testCallback.test();
    testCallback.error(new Exception("test"));
    // 新增
    testCallback.error(null);
}

即使我們在error()調(diào)用的地方傳入null也不會出現(xiàn)什么問題,因?yàn)槲覀冊诨卣{(diào)實(shí)現(xiàn)的時候加入了非空判斷,但是我們使用Convert Java File 2 Kotlin File轉(zhuǎn)換成Kotlin之后再看看代碼

class Java2Kt {
    private val testCallback = Test()
    fun test() {
        testCallback.setTest(object : TestCallback {
            override fun test() {
                Log.d("taonce", "Java2Kt test")
            }

            override fun error(e: Exception) {
                if (e != null) {
                    Log.d("taonce", "Java2Kt error " + e.message)
                }
            }
        })
    }
}

這樣乍一看是不會出現(xiàn)問題的,因?yàn)檗D(zhuǎn)換成KT之后,非空判斷也是有的,但是此時AS會在非空判斷的地方報警告??,提示我們Condition 'e != null' is always 'true',習(xí)慣性的就會將這個非空給去掉,去掉之后一運(yùn)行直接來了一個空指針異常??

分析

AS的Convert Java File 2 Kotlin File功能在轉(zhuǎn)換過程中,如果參數(shù)未使用可空或者非空注解,轉(zhuǎn)換之后默認(rèn)是非空類型,這樣就會導(dǎo)致我們在使用的時候不太注意此參數(shù)的可空類型,有時會丟掉可空檢查,這樣在程序運(yùn)行的過程中就會出現(xiàn)空指針的可能,再來看看直接使用KT實(shí)現(xiàn)回調(diào)的代碼

test.setTest(object : Test.TestCallback {
    override fun test() {
        Log.d("taonce", "MainActivity test")
    }
    // 默認(rèn)為可空類型
    override fun error(e: Exception?) {
        Log.d("taonce", "MainActivity test ${e?.stackTraceToString()}")
    }
})

如果直接使用KT來編碼,實(shí)現(xiàn)TestCallback的時候error(exception?)是默認(rèn)加上了可空(?)的,很明確的告知開發(fā)者需要注意此參數(shù)可能為空,需要在使用的時候加上可空判斷。所以直接使用KT是大概率的不會出現(xiàn)空指針的情況了。

小結(jié)

  1. AS的Convert Java File 2 Kotlin File功能固然是給開發(fā)者提供了便捷的操作,但是也需要開發(fā)者使用之后謹(jǐn)慎判斷
  2. 對于自己使用Java寫的一些回調(diào),盡可能的加上可空或者非空的注解,可以給調(diào)用者提供一些警示信息
  3. 在日常編碼中,編碼細(xì)節(jié)一定要處理得當(dāng),空指針無可避免但也需要最大化的避免此種異常,KT在這方面已經(jīng)為開發(fā)者提供了較為安全的操作了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容