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 runnable
s 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