Question on default final on classes and interoperation with existing cglib ecosystem


#1

Don't know if such questions might be discussed or proposed. Still I have to try ).

Kotlin is very promising language: it has a lot of nice, productive and safe features and still it’s integreated well with existing java ecosystem (as opposed to clever scala which is pain to integrate into java ecosystem because of different collection classes, different property naming and extra Option for nullness).

Still one thing makes some pain now and would do in future. This is final and suppressing inheritence by default.

There are two worlds in current java: user-space where we write code, where private’s are honored and code quality must be high. And some kind of meta-space where all introspection, AOP and other frameworks live (Spring AOP, Hibernate Validator, Hibernate ORM, Mockito and company). Theese could easyly access private’s through reflection, make proxies to whatch for methods and so. And this is OK. While I don’t want class extension in userspace, I don’t mind if serialization framework access private state to serialize it or if proxy is created to add transaction support or make some magical stuff with access recording.

Right now in Kotlin to enable it you have to write open open open all the way (properties, functions, classes). And it isn’t that you wish your class to be extensible in user space: you just need it for things to work.

There might be some kind of “hack” solution: to make this “default not-open” state Kotlin internal so to forbid such extension on user level but keep it non-final at bytecode level.  While it’s agly and it’ll require platformFinal to make things really final for bytecode where it’s needed, it could keep user-space clean and expressive and allow tools to make their dirty but very usefull job.

What do you think about this topic? Are there other solutions or very open world is our future?


#2

+1

Yeah this is so frustating. I also want to open this question but already found this.

The most frustating part is that I cannot extend any Java class nor override any member of it, because everything is final or being hidden.
The only way I can overcome this is by creating java classes that extend those classes and using it in Kotlin.

I though that I only need to code Kotlin. This is very inconvenience and weird.


#3

We are considering to change the defaults here, although it's not so obvious a decision


#4

I think it would be a shame to change the defaults to handle this kind of interop. This is a problem that only affects a subset of cases but changing the defaults would affect all users of the language. And everyone seems to agree that having things final by default is a good thing from the point of view of language design.

Would it be possible to have single annotation applied to the class that has the effect of making every member of that class open - methods, properties and the class itself? It could be used to handle these cases without affecting everyone. Maybe it should be in a package that means you have to explicitly import it. That would help make it clear it’s intended for a specific use case.

Also, would it be possible for it to just affect the bytecode so the class still can’t be extended in Kotlin code? Or does the compiler rely on the bytecode rather than Kotlin-specific metadata to know whether something is open?