Статическое конечное поле равно нулю, если оно не должно - PullRequest
0 голосов
/ 22 октября 2018

В нашем приложении есть код, использующий Java, и другой, использующий Kotlin.Мы столкнулись с очень странной ситуацией.

Проблема обнаруживается на некоторых устройствах, где она сообщает platform как null при передаче его конструктору AutoValue_Session, несмотря на то, что мы проверяем, является ли lastPlatform не null, и предоставляют постояннуюPlatform.MISSING в противном случае:

Caused by java.lang.NullPointerException: Null lastPlatform
x.x.x.x.AutoValue_Session.(SourceFile:27)
x.x.x.x.Session.from(SourceFile:28) // from that calls the child constructor
x.x.x.x.Session.(SourceFile:22) // whereNONE_FOUND is defined
x.x.x.x.Session.from(SourceFile:32) // entry point
[...]

У кого-нибудь была эта проблема с взаимодействием Android и Kotlin?

Обновление: Это происходит в дикой природе и с небольшим количеством пользователей.Пока не удается реплицировать его локально.

Обновление 2: Второй вызов Session.from вызван <clinit> из Session, который загружается в память дляпервый раз.

Вот код для двух упомянутых классов:

Platform.kt

sealed class Platform {

    abstract val name : String

    sealed class Local : Platform() {

        object Default : Local() {
            override val name: String = "android"
        }

        object Amazon : Local() {
            override val name: String = "android-amazon"
        }
    }

    object Missing : Platform() {
        override val name: String = "missing"
    }

    data class Remote(override val name: String) : Platform()

    companion object {
        @JvmName("from")
        @JvmStatic
        operator fun invoke(name: String?): Platform = when (name) {
            Local.Default.name -> Local.Default
            Local.Amazon.name -> Local.Amazon
            Missing.name -> Missing
            null -> Missing
            else -> Remote(name)
        }

        @JvmField
        val LOCAL : Platform = if (BuildConfig.amazon) Local.Amazon else Local.Generic

        @JvmField
        val MISSING : Platform = Missing
    }
}

Session.java

@AutoValue
public abstract class Session implements Serializable {

    public static final Session NONE_FOUND = from(0, new DateTime(0), Platform.MISSING);

    public static Session from(String id, @Nullable Platform lastPlatform) {
        Platform platform = lastPlatform == null ? Platform.MISSING : lastPlatform;
        return new AutoValue_Session(id, platform);
    }

    public static Session from(RemoteSession remote) {
        return from(
                remote.id(),
                remote.lastPlatform()
        );
    }

    public abstract String id();

    public abstract Platform lastPlatform();

}
...