ожидать, что абстрактный класс с аргументом по умолчанию не генерирует метод $ default stati c - PullRequest
0 голосов
/ 26 января 2020

Допустим, у меня есть класс, как показано ниже:

abstract class AbsTest {
    fun test(k: String, v: String? = null) {
        println("Key - $k, Value - $v")
    }
}

И класс, который наследует от него:

class Test : AbsTest { ... }

Моя основная функция выглядит примерно так:

fun main() {
    Test().test("Hello")
}

Это работает абсолютно нормально. Однако, если я сделаю это в Kotlin Multi-platform, то произойдет сбой. Вот мой код KMP:

expect abstract class AbsTest {
    fun test(k: String, v: String? = null)
}

// Android Target
actual abstract class AbsTest {
    fun test(k: String, v: String?) { ... }
}

class Test : AbsTest { ... }

// Calling Place
fun finalTest() {
    Test().test("Hello")
}

Приведенный выше код KMP выдает следующее исключение:

java.lang.NoSuchMethodError: No static method test$default(...) in class AbsTest found

Из любопытства, когда я декомпилировал код для проверки сгенерированного байт-кода, я обнаружил проблема в том, что он не генерирует метод $ default для проекта KMP, где как другой работает нормально.

Декомпилированный код (обычный Kotlin проект)

public abstract class AbsTest {
    public final void test(@NotNull String k, @Nullable String v) {
        ...
    }
    public static void test$default(AbsTest var0, String var1, String var2, int var3, Object var4) {
        ...
    }
}

Декомпилированный код (KMP проект)

public abstract class AbsTest {
    public final void test(@NotNull String k, @Nullable String v) {
        ...
    }
    // No test$default() method generated
}

Есть ли причины, почему KMP ведет себя так? Как это исправить?

1 Ответ

0 голосов
/ 26 января 2020

Вы уже нашли проблему, как вы заявили. Компилятор kotlin почему-то не компилирует методы по умолчанию. Однако в качестве обходного пути вы можете использовать два разных метода следующим образом.

expect abstract class AbsTest {
    // fun test(k: String, v: String? = null)
    fun test(k: String)
    fun test(k: String,v: String?)
}

// Android Target
actual abstract class AbsTest {
    fun test(k: String) { . . .}
    fun test(k: String, v: String?) {
        if(v==null){
            test(k);
        }
        . . .
    }
}

Надеюсь, это поможет

...