Какие конструкции в Kotlin упрощают интероп с Java
Что проверяют
Понимаете ли вы, как Kotlin-код выглядит со стороны Java и наоборот. В Android смешанный код обычное дело: старые модули, Java-библиотеки, сам SDK. Следом спрашивают про платформенные типы и про то, откуда в Kotlin берётся NullPointerException.
Как отвечать
Когда Java вызывает Kotlin:
@JvmStatic: метод изcompanion objectстановится статическим, иначе Java пишетFoo.Companion.bar();@JvmField: свойство видно как поле без геттера; для примитивов и строк хватаетconst val;@JvmOverloads: перегрузки для параметров со значениями по умолчанию, типичный случай это конструкторы кастомнойView;@JvmName: имя в байткоде, в том числе у файла через@file:JvmName, иначе функции верхнего уровня лежат в классеUtilsKt;@Throws: проверяемых исключений в Kotlin нет, и без аннотации Java не сможет пойматьIOException, компилятор сочтётcatchнедостижимым.
Когда Kotlin вызывает Java:
- платформенные типы (
String!): компилятор не знает проnull. Аннотации@Nullableи@NonNullизandroidx.annotationили JSpecify превращают их в обычные типы; - SAM-преобразование: Java-интерфейс с одним методом принимает лямбду, для своих интерфейсов есть
fun interface; - геттеры и сеттеры читаются как свойства:
view.visibilityвместоgetVisibility().
Добавьте, что функции-расширения компилируются в статические методы с получателем первым параметром, а коллекции Kotlin в рантайме это обычные java.util.List и java.util.Map.
Где спотыкаются
Доверяют платформенному типу: кладут результат Java-метода в String без проверки и получают NPE на этой строке.
Считают List из Kotlin неизменяемым. Интерфейс только для чтения, а Java может вызвать add и получить UnsupportedOperationException или молча изменить список, если под ним ArrayList.
Ждут от @JvmOverloads всех комбинаций. Перегрузки отбрасывают параметры с конца по одному, поэтому пропустить средний аргумент из Java нельзя.