Конвертер 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 аргумента savedInstanceStateBundle где он должен быть Bundle? потому что это значение может быть null .

В этом случае мы получим следующее исключение, если действие создано без состояния экземпляра:

 java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState 

Обратите внимание: основной причиной этого может быть то, что в документации onActivityCreated не упоминается, что Bundle может быть нулевым, тогда как документация 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 аннотация не помогает здесь.

Если аннотации не помогают, я не думаю, что есть способ узнать, является ли аргумент нулевым или нет.

Что касается вашего опубликованного кода, я думаю, что знаю, что происходит:

Активность 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 …) Я не удивлюсь, если переводчик Котлин признает только некоторые из них (но это всего лишь предположение)

Кроме того, что касается вашего кода, Java Lint должен был дать вам предупреждение о вашем переопределенном onCreate , сказав, что вы переопределяете метод с аннотированными параметрами, и вы его не аннотировали.