Java 到 Kotlin 转换器和可为 null 的方法参数
Java to Kotlin converter and nullable method arguments
我遇到过 Java 到 Kotlin 转换器的情况,因为没有将方法参数标记为可为空,所以我惨遭失败。
示例:使用 registerActivityLifecycleCallbacks
跟踪 activity 生命周期:
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 doesn't mention that Bundle
can be null whereas 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 注释在这里没有帮助。
如果注释没有帮助,我认为没有办法知道参数是否可为空。
关于您发布的代码,我想我知道发生了什么:
Activity 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。但是我可以理解该决定是为了迫使开发人员注意翻译后的代码并明确决定参数是否为 Nullable。
顺便说一下,请注意有几个 @NonNull
和 @Nullable
注释(javax、android、jetbrains ...)如果 Kotlin 翻译器只有认识其中一些(但这只是猜测)
关于您的代码,Java Lint 应该已就您的重写 onCreate
向您发出警告,说明您正在重写带有注释参数的方法,但您尚未对它们进行注释。
我遇到过 Java 到 Kotlin 转换器的情况,因为没有将方法参数标记为可为空,所以我惨遭失败。
示例:使用 registerActivityLifecycleCallbacks
跟踪 activity 生命周期:
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 doesn't mention that Bundle
can be null whereas 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 注释在这里没有帮助。
如果注释没有帮助,我认为没有办法知道参数是否可为空。
关于您发布的代码,我想我知道发生了什么:
Activity 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。但是我可以理解该决定是为了迫使开发人员注意翻译后的代码并明确决定参数是否为 Nullable。
顺便说一下,请注意有几个 @NonNull
和 @Nullable
注释(javax、android、jetbrains ...)如果 Kotlin 翻译器只有认识其中一些(但这只是猜测)
关于您的代码,Java Lint 应该已就您的重写 onCreate
向您发出警告,说明您正在重写带有注释参数的方法,但您尚未对它们进行注释。