受保护的成员无法通过扩展功能访问?

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方法。 一般而言,它们位于另一个类中,而不是它们扩展的类中的其他类,所以由于VM可访问性规则,无法调用该类的受保护方法。 它也与protected可见性定义 (在类及其子类中可见)一致:扩展函数不是子类,也不是在要扩展的类的子类中定义的。

您可以在扩展函数的主体中使用或省略this事实只是一个语法功能,编译器会发出所需的指令来加载JVM方法的第一个参数。