kotlin和java相互继承空判断问题记录

214 阅读1分钟

背景

SDK/Android 源码里的API用java编写,程序员用kotlin扩展这些API时会遇到空判断难处理的边界问题。

具体业务背景

kotlin 重写GestureDetector的onFling时,由于父类java代码中onFling参数用@NonNull 源码级注解声明,导致kotlin重载时只能用非空类型。但是业务崩溃平台还会报NPE。

Parameter specified as non-null is null: method kotlin.jvm.internal.o.h, parameter e1

问题原因

listner调java方法时,即使参数为null,运行时不会报NPE,但调到kotlin代码后,参数的空检查就会报错.而此时我们如果把kotlin中的onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float)改成onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float) 则编译期不能通过继承的语法检查。

父类GestureDetector.SimpleOnGestureListener
public boolean onFling(@NonNull MotionEvent e1, @NonNull MotionEvent e2, float velocityX,
        float velocityY) {
    return false;
}

子类kotlin重写
mGestureDetector = GestureDetectorCompat(requireActivity(), object : SimpleOnGestureListener() {
    override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
            ...
    }
})

解决方法

用java子类包一层SDK里的代码,具体如下

GestureDetectorJavaDelegate.java
class GestureDetectorJavaDelegate extends GestureDetector.SimpleOnGestureListener {

   @Override
   public boolean onFling(@Nullable MotionEvent e1, @Nullable MotionEvent e2, float velocityX, float velocityY) {

      return super.onFling(e1, e2, velocityX, velocityY);
   }
}

子类kotlin重写
mGestureDetector = GestureDetectorCompat(requireActivity(), object : GestureDetectorJavaDelegate() {
    override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
            ...
    }
})

kotlin和java混编时,还有比较容易出错的点:juejin.cn/post/723815…