Защищенные члены недоступны в функциях расширения?

В Kotlin есть несколько модификаторов видимости, а также функции расширения . В документации указано, что Extensions are resolved statically . Но что это означает для видимости членов класса в функциях расширения?

Рассмотрим следующий надуманный пример:

 class A { protected val a = "Foo" } fun A.ext() { print(a) } //Raises: Cannot access 'a': it is 'protected' in 'A' class B { val b = "Bar" } fun B.ext() { print(b) } //Compiles successful 

Код не будет компилироваться. Кажется, что защищенные члены недоступны при расширении класса.

Таким образом, решение статически означает, что функция расширения является синтаксическим сахаром для того, чтобы что-то подобное в Java:

 public static void ext(A receiver){ System.out.print(receiver.a); } 

Это объясняет, почему защищенные члены недоступны. С другой стороны, в функциях расширения можно использовать (и даже опустить).

Итак, каков точный объем функций расширения?

Вы правы, функции расширения / свойства скомпилированы для статических методов JVM. Как правило, они находятся в другом классе в каком-то другом пакете, чем в классе, который они расширяют, поэтому невозможно вызвать защищенные методы этого класса из-за правил доступности виртуальной машины. Это также согласуется с protected определением видимости (видимым в классе и его подклассах): функция расширения не является подклассом и не определена в подклассе класса, который вы расширяете.

Тот факт, что вы можете использовать или опустить this в теле функции расширения, является только синтаксической функцией, компилятор испускает необходимые инструкции для загрузки первого параметра JVM-метода.