На этом шаге мы рассмотрим, как представляется расширение.
Функции-расширения, или свойства-расширения, вызываются так же, как обычные, но определяются не внутри класса, который расширяют, и не используют механизм наследования для добавления новых возможностей. Так как же тогда расширения реализованы в JVM?
Чтобы понять, как расширения работают в JVM, заглянем в байт-код, сгенерированный компилятором Kotlin для расширения, и переведем его на язык Java.
Откройте окно инструментария байт-кода Kotlin, либо выбрав в меню пункт Tools | Kotlin | Kotlin Bytecode, либо введя запрос "show Kotlin bytecode" в диалоговом окне SearchEverywhere (двойной Shift).
В окне байт-кода Kotlin щелкните на кнопке Decompile вверху слева, чтобы открыть новую вкладку с Java-версией байт-кода, сгенерированного из Extensions.kt. Найдите байт-код расширения addEnthusiasm, которое вы определили для String:
public static final String addEnthusiasm(@NotNull String $this$addEnthusiasm, int amount) { Intrinsics.checkParameterIsNotNull($this$addEnthusiasm, "$this$addEnthusiasm"); return $this$addEnthusiasm + StringsKt.repeat((CharSequence)"!", amount); }
Рис.1. Java-версия байт-кода
В Java-версии байт-кода расширение Kotlin - это статический метод, который при компиляции для JVM принимает объект расширяемого класса в качестве аргумента. Компилятор заменяет вызов функции addEnthusiasm() вызовом этого статического метода.
На следующем шаге мы рассмотрим извлечение в расширения.