记录一次Java Convert Kotlin造成的空指针异常

不知道大家在使用Kotlin进行编码的时候,有没有直接使用AS的Code -> Convert Java File 2 Kotlin File这个功能,此功能在日常使用中还是比较实用的,可以帮助我们将老的Java或者复制的Java代码一键转换成Kotlin代码,最近在使用此功能的时候竟然遇到了空指针的Crash,在此记录一下,顺便也给大家做个预警。

起因

在工程中引入了三方的SDK,此SDK使用Java编码,我们需要实现它的一个回调方法做一下异常处理,SDK具体方法就不贴出来了,下面模拟一下他们的回调

public class Test {
    
    

    // 定义回调接口,其中error用来处理异常情况,参数为Exception对象
    public interface TestCallback {
    
    
        void test();

        void error(Exception e);
    }

    // 传入回调并直接模拟调用它的方法
    public void setTest(TestCallback testCallback) {
    
    
        testCallback.test();
        testCallback.error(new Exception("test"));
    }
}

模拟了它们的回调接口,然后在setTest(callback)中直接调用接口方法,这里先看一下这个error的接口方法,它的参数exception并没有使用可空(@Nullable)或者非空(@NonNull)注解来定义,默认就是可空类型。

然后我们直接模拟调用下看看具体效果,先用Java代码来调用

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

这样就没得毛病,可以正确调用并输出日志,然后我们改一下setTest(callback)方法,再额外添加一行

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

即使我们在error()调用的地方传入null也不会出现什么问题,因为我们在回调实现的时候加入了非空判断,但是我们使用Convert Java File 2 Kotlin File转换成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)
                }
            }
        })
    }
}

这样乍一看是不会出现问题的,因为转换成KT之后,非空判断也是有的,但是此时AS会在非空判断的地方报警告,提示我们Condition 'e != null' is always 'true',习惯性的就会将这个非空给去掉,去掉之后一运行直接来了一个空指针异常

分析

AS的Convert Java File 2 Kotlin File功能在转换过程中,如果参数未使用可空或者非空注解,转换之后默认是非空类型,这样就会导致我们在使用的时候不太注意此参数的可空类型,有时会丢掉可空检查,这样在程序运行的过程中就会出现空指针的可能,再来看看直接使用KT实现回调的代码

test.setTest(object : Test.TestCallback {
    
    
    override fun test() {
    
    
        Log.d("taonce", "MainActivity test")
    }
    // 默认为可空类型
    override fun error(e: Exception?) {
    
    
        Log.d("taonce", "MainActivity test ${e?.stackTraceToString()}")
    }
})

如果直接使用KT来编码,实现TestCallback的时候error(exception?)是默认加上了可空(?)的,很明确的告知开发者需要注意此参数可能为空,需要在使用的时候加上可空判断。所以直接使用KT是大概率的不会出现空指针的情况了。

小结

  1. AS的Convert Java File 2 Kotlin File功能固然是给开发者提供了便捷的操作,但是也需要开发者使用之后谨慎判断
  2. 对于自己使用Java写的一些回调,尽可能的加上可空或者非空的注解,可以给调用者提供一些警示信息
  3. 在日常编码中,编码细节一定要处理得当,空指针无可避免但也需要最大化的避免此种异常,KT在这方面已经为开发者提供了较为安全的操作了

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题

猜你喜欢

转载自blog.csdn.net/datian1234/article/details/130932082