In library development, compatibility is key. So i...
# library-development
d
In library development, compatibility is key. So if you expose an interface to implement (SPI), it’s important not to break implementations all the time. So if you need to add a new method to an interface, you cannot simply leave it unimplemented, because it will fail after recompile. Java 8 solves it with default methods. In order to produce Java 8 default methods from Kotlin, you gotta use
@JvmDefault
. But then the library consumers still fail recompilation:
Inheritance from an interface with ‘@JvmDefault’ members is only allowed with -Xjvm-default option
. Did you ever encounter this? If so, what did you do? Added a new library requirement and released a major (SemVer backwards incompatible) version?
l
d
Yes, this page explains how to produce such interfaces, but doesn’t explain the additional requirement for the implementations.
e
Extension functions in Kotlin for most part abolish the need to add more methods to interfaces in future updates, so we hardly ever encounter this problem.
That is exactly what I meant when I said “hardly ever” 🙂 If you analyze large JDK interfaces with tons of methods, then most of those methods do not benefit from polymorphism and would work just as well as extensions. Situations where you truly need to add a new polymorphic method to an existing interface are quite rare in practice and often, if this interface had been widely adopted (there are delegate/adapter impls, etc) adding Java default method is not viable solution either.
I does happen, though. So java default methods do have their uses.
d
Indeed. It's especially useful when you want to be nice to your API consumers and SPI producers and not break them unless absolutely necessary. Even if the interfaces have adapters and delegates, default methods help. Adapters are just another API consumers and delegates are yet another SPI implementors.