Extension methods and visibility


I just played around a bit with extension methods in Kotlin. So I created some class Foo with an instance variable bar. Then I added a Kotlin file into the same namespace as Foo with an extension method printIt that prints Foo’s bar to the console.

Now I changed the visibility of bar to protected. As a result the extension method printIt does not compile any more, because it can’t see bar any more. That surprised me. Class Foo and the Kotlin file that adds an extension method to it are in the same namespace.

I checked this out with Scala using their implicit conversion mechanism and it was the same thing. So I guess it must be a restriction of the JVM. Unhappily, this restriction does not make sense. Classes/files in the same package should be able to see each other’s vars and methods if they are declared public or protected. I checked it out in Swift where this is the case, see 3 Nuances of Swift Extensions

Any chance this can be backed up in the future in Kotlin or definitely a JVM issue?

Regards, Oliver

Well, this is not how protected visibility works in Kotlin. protected means “visible to that class and its subclasses”, nothing more; the namespace in which the class is defined doesn’t play any role in determining the visibility of its protected members. This is not, strictly speaking, a JVM issue (because protected has broader visibilty on the JVM), but this was a conscious design decision in Kotlin that we don’t have any plans to change at this time.

I found a way to do it in Scala. The protected modifier can be qualified with the package name. However, that does not buy you much. You have to provide the same package name as the package the extended class resides in. If that is the case you own the package anyway and can add the method to the class right away without a need for an extension method.