Найти в Дзене

Аннотация @JvmStatic в Kotlin

Оглавление

Наверное, многие из нас видели в коде аннотацию @JvmStatic и выглядит так, что она достаточно простая. Аннотация помогает сделать методы и свойства статическими в контексте Java. Казалось бы, а что еще тут говорить? Я тоже так думала, а набралось на целую статью.

Зачем вообще нужна эта аннотация?

Когда мы пишем код на Kotlin, наши котики классы и объекты по умолчанию не имеют статических методов или свойств, как это принято в Java. Вместо этого Kotlin предлагает нам использовать companion objects. Однако, иногда нам нужно, чтобы методы и свойства выглядели статическими для кода на Java. Здесь на помощь приходит @JvmStatic.

Пример:

Допустим, у нас есть котик, который мяукает:

Если мы попытаемся вызвать этот метод из Java, код будет выглядеть так:

-2

И вот выглядит не очень удобно, что появляется какой-то INSTANCE и нельзя просто написать Barsik.meow().

Кому интересно откуда INSTANCE, то вот как котлин код превращается в Java:

-3

Аннотация @JvmStatic поможет нам решить эту проблему.

-4

Теперь вызов из Java будет выглядеть привычно:

-5

Посмотрим как изменилась декомпиляция:

-6

Мы видим, что метод meow() стал статическим и, поэтому, теперь к нему можно обращаться напрямую.

Аналогично работает и для companion object. Можете проверить самостоятельно. Чтобы посмотреть декомпиляцию: Tools -> Kotlin -> Decompile to Java -> Ждем немного -> жмякаем кнопочку Decompile.

Пример с параметрами:

-7

Здесь у нас @JvmStatic используется для defaultName в компаньон-объекте. Каких-то проблем нет и мы спокойно в Java сможем получить через Cat.getDefaultName()

Декомпилированный код выглядит так:

-8
-9

Ничего необычного нет и всё вполне логично преобразуется. А теперь к самому интересному: что будет, если написать @JvmStatic вне object?

-10
-11

У нас даже не получится скомпилировать такой код. Но почему?

  1. @JvmStatic предназначена для создания статических методов и свойств, которые могут быть вызваны без создания экземпляра класса. В Kotlin статические методы и свойства реализуются через object. Если свойство или метод объявлены в другом месте, то они принадлежат конкретному котику, а не вообще всем котам в мире.
  2. Kotlin компилятор генерирует байт-код JVM, который обеспечивает совместимость с Java. В Java и JVM конструкторы не могут иметь статических параметров. Конструктор всегда работает с конкретным экземпляром котика, и параметры конструктора не могут быть статическими, так как каждый котик уникален и имеет своё собственное имя и возраст.
-12

Дубль статей в телеграмме — https://t.me/android_junior

Мои заметки в телеграмме — https://t.me/android_junior_notes