Hello, I’ve had this strange unexpected issue recently, please tell me if I’m missing something.
I’ve the following in Kotlin
typealias KtLogFun = (String, Throwable) -> Unit
typealias JavaLogFun = BiConsumer<String, Throwable>
fun logJava(log: JavaLogFun) {}
fun logKt(log: KtLogFun) {}
fun log(log: KtLogFun) {}
fun log(log: JavaLogFun) {}
And those log methods have to be called from both Kotlin and Java. Here’s the Java side
class Person {
private static final Logger logger = LoggerFactory.getLogger(Person.class);
private void doSomething() {
// this works
logJava(logger::debug);
// this fails with Function2<String,Throwable> cannot be applied to <method reference>
// that's expected as Unit != void
logKt(logger::debug);
//this works
log(((BiConsumer<String, Throwable>) logger::debug));
// this fails with ambiguous method call. Both Function2 and BiConsumer match
log(logger::debug);
}
}
The call to logKt is expected to fail as it expects a function returning Unit and we are providing void.
The other one to log fails if I don’t cast to BiConsumer. I would have expected it to work since logKt(BiConsumer) fails but somehow it cannot differentiate both types.
My real life issue is with this logging function passed to secondary constructors and used a thousand times by consumers of my Api so the cast option is not a good alternative. I can’t also change constructor’s name. As a workaround I changed other constructor parameters order to have a clear method signature difference between Kotlin constructor and Java one.
I’ve searched and did not found a similar issue on youtrack. Is there a workaround I haven’t think of ?
Thanks