Because of Kotlin’s intrinsic support for nullable types, it is commonplace for Kotlin methods to return nullable types. Conversely, in Java, it is considered good practice for methods to return Optional
types, providing explicit handling of nullable values.
When dealing with methods used in both Java and Kotlin, a suggested approach is to initially define methods that return Optional
for Java callers. Simultaneously, implement corresponding Kotlin extension functions that return nullable types.
For example, consider the following interface that already specifies a return type as Optional
:
public interface MyInterface {
Optional<Data> getData();
}
Then, create an extension function in Kotlin that returnsData?
:
@JvmSynthetic
fun MyInterface.data(): Data? = getData().getOrNull()
Due to naming conflicts, it might be challenging to give these methods identical names ……
Additionally, I also prefer applying the @JvmSynthetic
annotation. It helps restrict access to the extension function from Java, ensuring it is only accessible to Kotlin callers.
Note that the use of @JvmSynthetic
affects stack traces, leading to the elision of annotated methods from JVM stack traces. Alternatively, you can use @JvmName
with an invalid Java name to conceal the method from Java:
@JvmName("-data")
fun MyInterface.data(): Data? = getData().getOrNull()
This approach achieves the same goal of restricting Java access.