I have a collection of utilities that I use both from my existing Java code and new Kotlin code. Among those are often utilities that take lambdas.
inline fun <T> foo(crossinline lambda : () -> T) : T {
[...]
return lambda()
}
When calling from Kotlin this is perfectly fine, because Kotlin does not have checked exceptions.
When calling from java, crossinline lambda
becomes a Function0<?>
. Note the absence of throw clauses.
So from Java, I can’t call
foo(() -> { if (worldNeedsSaving) { saveTheWorld(); } else throw new CheckedException(); });
…because Java will complain that CheckedException is not handled.
The only way I have found so far to make this work is to use Java functional classes.
@FunctionalInterface public interface ThrowingSupplier<T> {
T get() throws Exception;
}
inline fun <T> foo(lambda : ThrowingSupplier<T>) {
...
}
But this means the lambda can no longer crossinline, which has other drawbacks.
Intuitively I would say that either Kotlin, as a language without checked exceptions, should compile () -> T
into Function0<T> throws Exception
, or that I should be able to annotate my argument with @Throws.
Is there a better solution than mine above, in particular one that would let me keep crossinline ?