Несовместимость Nullability onSaveInstanceState и BaseSavedState - PullRequest
0 голосов
/ 27 апреля 2020

Я видел много примеров кодов в Java с пользовательским SavedState, используя простой шаблон

override protected Parcelable onSaveInstanceState() {
    final Parcelable superState = super.onSaveInstanceState();
    final SavedState mySavedState = new SavedState(superState)
    ...
    return mySavedState;
}

Все выглядит красиво и компилируется в Java, и МОЖНО работает нормально. SavedState конструктор вызывает BaseSavedState(Parcelable superState) конструктор, который вызывает protected AbsSavedState(Parcelable superState) конструктор.

Проблема заключается в том, что вы конвертируете это в Kotlin и начинаете принудительно обнулять. Вы быстро обнаружите, что View.onSaveInstanceState() - это Nullable, но конструктор AbsSavedState(Parcelable superState) проверяет суперсостояние на наличие нуля и создает исключение, если оно null.

Большую часть времени View.onSaveInstanceState() на самом деле not-null так что вы не нажмете исключение нулевого указателя. Но контракт понятен - он может быть нулевым. В этом случае у вас есть Cra sh.

В Kotlin, с другой стороны, у вас есть ошибка времени компиляции, которая не легко решаема, потому что что здесь делать правильно? Вы могли бы подумать, что вы просто соединяете две стороны водопровода, но с одной стороны есть выход nullable, а с другой стороны non-nullable Parcelable input.

Ирония в том, что AbsSavedState имеет также собственный конструктор, назначающий null в супер-состояние, чтобы он мог работать с обнуляемым супер-типом, но в любом случае есть эта нулевая проверка.

Это выглядит как неумышленное несоответствие для меня. Я ожидал бы, что эти состояния будут совместимы с обеих сторон, и в Java никто действительно не заботился о том, чтобы проверить исходный код, действительно ли он принимает обнуляемые типы, предполагая, что все в порядке. И это работало хорошо для большинства, пока какая-то странная реализация не вернула null.

Но что должно быть правильным способом здесь. Это действительно ошибка или смещение в исходном коде? Может кто-нибудь пролить свет на это?

...