【发布时间】:2017-10-09 23:25:38
【问题描述】:
我有一个案例,Java 到 Kotlin 的转换器因为没有将方法参数标记为可为空而使我悲惨地失败了。
示例:使用registerActivityLifecycleCallbacks跟踪活动生命周期:
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivityStarted(Activity activity) {}
@Override
public void onActivityResumed(Activity activity) {}
// ... other overriden methods
});
将此代码粘贴到 Kotlin 结果:
registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
// ... other overriden methods (all with non-nullable parameters)
})
问题是savedInstanceState 参数类型是Bundle,它应该是Bundle?,因为它的值可以是null。
在这种情况下,当Activity 在没有实例状态的情况下创建时,我们将得到以下异常:
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
注意,造成这种情况的根本原因可能是 onActivityCreated documentation 没有提到 Bundle 可以为 null 而 onCreate documentation 这样做可以解释为什么简单的 onCreate 转换可以作为预期:
// Java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
我的问题是我们如何知道哪些参数应该可以为空以防止此类问题? @Nullable 注释在这里没有帮助。
【问题讨论】:
标签: java android kotlin kotlin-android-extensions kotlin-null-safety