Как избавиться от суффикса Kt в названиях классов Kotlin при вызове из Java
Что проверяют
Знаете ли вы, откуда берётся Kt: его получает не класс, а файловый фасад, в который компилятор складывает функции и свойства верхнего уровня. Следом обычно спрашивают, как вызвать из Java функцию из companion object без .Companion и что делать с аргументами по умолчанию.
Как отвечать
Начните с механики: функции верхнего уровня из файла StringUtils.kt попадают в JVM-класс StringUtilsKt, и из Java вызов выглядит как StringUtilsKt.capitalize(s). Классы, объявленные в Kotlin, свои имена сохраняют, суффикса у них нет.
Способы убрать суффикс:
@file:JvmName("StringUtils"): аннотация файла, ставится в самом начале, доpackage. Из Java вызов становитсяStringUtils.capitalize(s);@file:JvmMultifileClass: вместе с одинаковым@file:JvmNameв нескольких файлах собирает их в один фасад. Без неё два файла с одним именем фасада дадут ошибку компиляции;objectс@JvmStatic: связанные функции можно положить вobject StringUtils, а@JvmStaticсделает их настоящими статическими методами. Без аннотации из Java придётся писатьStringUtils.INSTANCE.capitalize(s);companion object: то же самое,@JvmStaticубирает.Companionиз вызова, а для констант подходятconst valили@JvmField.
Для полноты назовите соседние аннотации совместимости: @JvmOverloads генерирует перегрузки для параметров по умолчанию, а @JvmName на функции разводит сигнатуры, которые совпали после стирания типов, например fun sum(list: List<Int>) и fun sum(list: List<Double>).
Где спотыкаются
Ставят @JvmName на класс. К классу эта аннотация не применяется, она работает на файле, функции и аксессорах свойства.
Путают фасад с классом и думают, что суффикс получает любой Kotlin-класс. Интервьюер сразу уточнит, откуда тогда Kt у файла без единого класса.
Переименовывают фасад в опубликованной библиотеке и забывают про бинарную совместимость: Java-код, собранный против StringUtilsKt, упадёт с NoClassDefFoundError, а правила R8 и рефлексия по имени класса тоже потребуют правки.