Java to Kotlin转换器和可空方法参数

我遇到了一个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文档 没有提到Bundle可以为null,而onCreate文档可以解释为什么简单的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注解在这里没有帮助。

One Solution collect form web for “Java to Kotlin转换器和可空方法参数”

如果注释没有帮助,我不认为有一种方法可以知道一个参数是否可以为空。

关于你的发布代码,我想我知道发生了什么事情:

活动onCreate IS标记为@Nullable

 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { final AppCompatDelegate delegate = getDelegate(); delegate.installViewFactory(); delegate.onCreate(savedInstanceState); . . 

虽然ActivityLifecycleCallbacks接口方法不是 :(请参阅Application.java

 public interface ActivityLifecycleCallbacks { void onActivityCreated(Activity activity, Bundle savedInstanceState); void onActivityStarted(Activity activity); void onActivityResumed(Activity activity); void onActivityPaused(Activity activity); void onActivityStopped(Activity activity); void onActivitySaveInstanceState(Activity activity, Bundle outState); void onActivityDestroyed(Activity activity); } 

所以显然Kotlin翻译器正在处理注释,但是使用Non-Null作为默认值,这在我看来并不常见,因为对于未注释的参数来说,将其视为Nullable更有意义。 不过,我可以理解这个决定,以便强迫开发人员注意翻译的代码,并明确地决定参数是否为

顺便说一下,介意有几个@NonNull@Nullable注释(javax,android,jetbrains …)如果Kotlin翻译只识别其中的一部分,我不会感到惊讶(但这只是一个猜测)

另外关于你的代码,Java Lint应该给你一个关于你重载的onCreate的警告,说你重写了带有注释参数的方法,但是你没有注释它们。

  • Kotlin对类属性无效
  • Kotlin:不能同时应用两个条件检查“return body”函数样式
  • 我如何使用Kotlin中的默认构造函数参数值实例化一个对象?
  • null to listOf(),not null to listOf(value)in Kotlin in one liner?
  • 如何使用自定义的类对象在android中的onCreate()中使用正确实现lateinit避免“属性获取或设置器预期”错误
  • 一个字段可以转换为非null版本本身?
  • 如何在基本类型中使用kotlin中的@Autowired或@Value等Spring注解?
  • 在可能为空的接收器types的数组列表中,只允许安全或非空的确定的呼叫
  • Kotlin在null上的非null断言
  • Kotlin无效检查错误
  • 处理一个可以在kotlin中返回null的对象
  • Kotlin language will be the best programming language for Android.