Наверное, многие из нас видели в коде аннотацию @JvmStatic и выглядит так, что она достаточно простая. Аннотация помогает сделать методы и свойства статическими в контексте Java. Казалось бы, а что еще тут говорить? Я тоже так думала, а набралось на целую статью.
Зачем вообще нужна эта аннотация?
Когда мы пишем код на Kotlin, наши котики классы и объекты по умолчанию не имеют статических методов или свойств, как это принято в Java. Вместо этого Kotlin предлагает нам использовать companion objects. Однако, иногда нам нужно, чтобы методы и свойства выглядели статическими для кода на Java. Здесь на помощь приходит @JvmStatic.
Пример:
Допустим, у нас есть котик, который мяукает:
Если мы попытаемся вызвать этот метод из Java, код будет выглядеть так:
И вот выглядит не очень удобно, что появляется какой-то INSTANCE и нельзя просто написать Barsik.meow().
Кому интересно откуда INSTANCE, то вот как котлин код превращается в Java:
Аннотация @JvmStatic поможет нам решить эту проблему.
Теперь вызов из Java будет выглядеть привычно:
Посмотрим как изменилась декомпиляция:
Мы видим, что метод meow() стал статическим и, поэтому, теперь к нему можно обращаться напрямую.
Аналогично работает и для companion object. Можете проверить самостоятельно. Чтобы посмотреть декомпиляцию: Tools -> Kotlin -> Decompile to Java -> Ждем немного -> жмякаем кнопочку Decompile.
Пример с параметрами:
Здесь у нас @JvmStatic используется для defaultName в компаньон-объекте. Каких-то проблем нет и мы спокойно в Java сможем получить через Cat.getDefaultName()
Декомпилированный код выглядит так:
Ничего необычного нет и всё вполне логично преобразуется. А теперь к самому интересному: что будет, если написать @JvmStatic вне object?
У нас даже не получится скомпилировать такой код. Но почему?
- @JvmStatic предназначена для создания статических методов и свойств, которые могут быть вызваны без создания экземпляра класса. В Kotlin статические методы и свойства реализуются через object. Если свойство или метод объявлены в другом месте, то они принадлежат конкретному котику, а не вообще всем котам в мире.
- Kotlin компилятор генерирует байт-код JVM, который обеспечивает совместимость с Java. В Java и JVM конструкторы не могут иметь статических параметров. Конструктор всегда работает с конкретным экземпляром котика, и параметры конструктора не могут быть статическими, так как каждый котик уникален и имеет своё собственное имя и возраст.
Дубль статей в телеграмме — https://t.me/android_junior
Мои заметки в телеграмме — https://t.me/android_junior_notes