André Diermann
André Diermann

Reputation: 2783

Protected members not accessible in extension functions?

Kotlin features a couple of visibility modifiers as well as extension functions. The documentation states that Extensions are resolved statically. But what does this mean for the visibility of class members within extension functions?

Let's consider the following contrived example:

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

The code will not compile. It seems that protected members are not accessible when extending the class.

So does resolved statically mean the extension function is syntactic sugar for having something like this in Java:

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

This would explain why protected members aren't accessible. On the other hand it's possible to use (and even omit) this in extension functions.

So what is the exact scope of extension functions?

Upvotes: 13

Views: 3658

Answers (1)

Alexander Udalov
Alexander Udalov

Reputation: 32776

You are correct, extension functions/properties are compiled to static JVM methods. Generally they are located in another class in some other package than the class they're extending, so it's not possible to call protected methods of that class due to VM accessibility rules. It's also consistent with the protected visibility definition (visible in the class and its subclasses): an extension function is not a subclass, nor is it defined in a subclass of the class you're extending.

The fact that you can use or omit this in the body of an extension function is only a syntactic feature, the compiler emits the required instructions to load the first parameter of the JVM method instead.

Upvotes: 20

Related Questions