Java到Kotlin转换器和可为null的方法参数



我遇到过一个案例,Java到Kotlin的转换器没有将方法参数标记为null,这让我非常失望。

示例:使用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注释在这里没有帮助。

如果注释没有帮助,我认为没有办法知道参数是否可以为null。

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

活动onCreateIS标记为@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更有意义。然而,我可以理解这个决定,以迫使开发人员注意翻译的代码,并明确决定参数是否为可为null

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

另外,关于您的代码,JavaLint应该向您发出一个关于被重写的onCreate的警告,说您正在用带注释的参数重写一个方法,而您没有对它们进行注释。

相关内容

最新更新