首页 > 编程语言 >记录一次Java Convert Kotlin造成的空指针异常

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

时间:2023-06-19 14:04:28浏览次数:63  
标签:Convert Java Kotlin error 可空 testCallback test


不知道大家在使用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在这方面已经为开发者提供了较为安全的操作了


标签:Convert,Java,Kotlin,error,可空,testCallback,test
From: https://blog.51cto.com/u_16163442/6512806

相关文章

  • 【Android面试】2023最新面试专题四:Java核心基础(上)
    1Java中提供了抽象类还有接口,开发中如何去选择呢?这道题想考察什么?Java是面向对象编程的,抽象是它的一大特征,而体现这个特征的就是抽象类与接口。抽象类与接口某些情况下都能够互相替代,但是如果真的都能够互相替代,那Java为何会设计出抽象与接口的概念?这就需要面试者能够掌握两者的区......
  • 在 JavaScript 中,判断一个对象是否为空有几种方法。
    使用Object.keys()方法检查对象的键值对数量:functionisObjectEmpty(obj){returnObject.keys(obj).length===0;}//示例用法constobj1={};console.log(isObjectEmpty(obj1));//输出:trueconstobj2={name:'John',age:25};console.log(isObjectEm......
  • API接口开发系列(获得京东JD商品详情原数据java源代码调用示例)
    请求获取京东商品详情原数据(免费获取调用请私信)的作用:1.提供商品信息:京东商品详情中的原数据可以提供商品的基本信息,包括商品名称、价格、品牌、规格参数、图片等,让消费者更好地了解商品。2.帮助搜索引擎识别:京东商品详情的原数据可以被搜索引擎识别,在搜索结果页中显示更为详细丰富......
  • Kotlin系列之不知道约定,可能有些代码你看不懂
    约定是kotlin语法当中必不可少的一部分,可以说kotlin语法的整洁,约定在里面扮演着不可缺少的角色,无论是在运算,比较,解构或者调用lanmda表达式上,都能看见约定的身影。二元运算符的约定java8里面的时间api大家一定不陌生,如果有不熟悉的可以看下我的这篇文章JAVA8中新的日期时间处理方式......
  • SprintBoot JavaWeb访问提示 Full authentication is required to access this resour
    SprintBoot部署好网站之后访问没有异常,但是配置域名地址至Nginx上时登录请求报错了,经查询是因为项目是前后端分离,请求的路由会加上工程的主路径,所以需要在Nginx多配置一个地址,如Location/{http://localhost:8080/project}location/project/{http://loc......
  • kotlin 和 r8 的量子纠缠 | 类加载机制偷鸡
    前言戏接上文,kotlin升级没想到啊还有一个大坑。我们之前说了我们使用的agp版本是7.0.3,在这个版本的R8竟然会出现kotlin混淆的bug。断更一个月,不更文的一个原因就是因为最近感觉太菜了,并没有文章素材了。问题排查接下来还是一点点进行问题分析,我们先从kotlin元数据开始讲这个问题。......
  • JavaScript 显示数据
    JavaScript显示数据JavaScript可以通过不同的方式来输出数据:使用window.alert()弹出警告框。使用document.write()方法将内容写到HTML文档中。使用innerHTML写入到HTML元素。使用console.log()写入到浏览器的控制台。window.alert()window.alert()是一个......
  • 使用Kotlin+Rretrofit+rxjava+设计模式+MVP封装网络请求
    0、前言:kotlin使用起来非常顺畅,尤其是结合rxjava、设计模式使用,你会发现写代码原来可以这么开心!什么?你还在使用java?赶紧去学一下kotlin吧!我相信你一定会对他爱不释手,kotlin也很容易学,花一天的时间就可以从java切换为kotlin一、正文本文主要介绍如何使用kotlin封装网络请求的工具,结......
  • 基于JAVA丝绸之路文化遗产信息发布和展示系统
    丝绸之路文化遗产是我们传统文化的精髓,是一代又一代传承人努力传承的成果,也是我们年轻人应该继承下去的文化瑰宝。而利用传承网站这样的与时代俱进的高新技术来表现和传承丝绸之路文化遗产这样的传统文化,无疑会让人们更加乐于接受和了解,间接的传播和保护了丝绸之路文化遗产。根据本......
  • 20230618 java.util.stream.Stream
    介绍java.util.stream.StreampublicinterfaceStream<T>extendsBaseStream<T,Stream<T>>APIstaticbuilder返回Builder创建流:ofofNullableempty创建无限流:iterategenerateconcat<T>Stream<T>concat(Stream<?ext......