Подтвердить что ты не робот

Статические данные в Котлине

Скажите, пожалуйста, какая разница (с точки зрения Java) в этом примере:

  • object DefaultValues {
        val FILES_TO_DOWNLOAD = 100
    }
    

    и

    class DefaultValues {
        companion object {
            val FILES_TO_DOWNLOAD = 100
        }
    }
    
  • Без оболочки класса или объекта:

    const val DEFAULT_FILES_TO_DOWNLOAD = 100
    

    и

    val DEFAULT_FILES_TO_DOWNLOAD = 100
    

Каков истинный способ определения?:

public static final int FILES_TO_DOWNLOAD = 100
4b9b3361

Ответ 1

Вы можете использовать просмотрщик байт-кода Kotlin, чтобы узнать, с чем скомпилированы эти параметры.

С Kotlin 1.0.2 скомпилированный байт-код показывает, что

  • val свойство в object или companion object скомпилировано в поле private static final внутри класса:

     // access flags 0x1A
     private final static I FILES_TO_DOWNLOAD = 100
    

    и getter, который вызывается при обращении к свойству:

     // access flags 0x1019
     public final static synthetic access$getFILES_TO_DOWNLOAD$cp()I
    

    Из Java геттер может быть вызван как DefaultValues.INSTANCE.getFILES_TO_DOWNLOAD() или DefaultValues.Companion.getFILES_TO_DOWNLOAD() соответственно.

  • Свойство верхнего уровня non- const скомпилировано с тем же значением (1) с той лишь разницей, что поле и геттер теперь помещаются внутри класса FilenameKt.

    Но верхний уровень const val скомпилирован в поле public static final:

    // access flags 0x19
    public final static I DEFAULT_FILES_TO_DOWNLOAD = 100
    

    То же самое публичное статическое конечное поле будет создано, когда в объекте объявляется const val. Кроме того, вы можете достичь того же полученного байт-кода, если добавить @JvmField аннотацию к свойствам, указанным в (1).


Завершая это, вы можете определить поле public static final, используя const или @JvmField либо в object, либо на верхнем уровне.