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

В 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); }

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

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

1 ответ

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

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

licensed under cc by-sa 3.0 with attribution.