java - Why is this val, not a val? -
this 1 seems dependant on interaction between java , kotlin, first java class:
public class myjavaclass { private runnable q; public void setrunnable(final runnable listener) { q = listener; } public boolean testcontains(final runnable listener) { return q == listener; } } now kotlin tests:
class javainteractiontests { @test fun `anonymous`() { val abc = object : runnable { override fun run() { } } val x = myjavaclass() x.setrunnable(abc) asserttrue(x.testcontains(abc)) } @test fun `lambda`() { val abc = runnable { } val x = myjavaclass() x.setrunnable(abc) asserttrue(x.testcontains(abc)) } @test fun `function`() { val abc: () -> unit = {} val x = myjavaclass() x.setrunnable(abc) asserttrue(x.testcontains(abc)) } } the last test fails, appear val isn't val.
bug or explainable, expected behaviour?
note, if java class defined in kotlin so, last test not compile:
class myktclass { private var q: runnable? = null fun setrunnable(listener: runnable) { q = listener } fun testcontains(listener: runnable): boolean { return q === listener } } (i noticed when registering callback java class, going remove later , failed removed. callback defined in 3rd test style)
the reason that, each time when call java function accepts runnable , pass kotlin function () -> unit it, runnable implicitly created wraps function.
and when twice (x.setrunnable(abc) , x.testcontains(abc)), these 2 different runnables not equal each other, hence failure.
this how sam conversion works in kotlin. basically, these calls equivalent
val abc: () -> unit = {} val x = myjavaclass() x.setrunnable(runnable(abc)) // 1 runnable asserttrue(x.testcontains(runnable(abc))) // runnable also, kotlin not support sam conversions functions defined in kotlin, that's why test not compile when re-write class in kotlin. reasoning kotlin has functional types, , should used instead of sam interfaces. so, sam conversion rather mean of java interop complete language feature.
Comments
Post a Comment