https://kotlinlang.org logo
Title
m

Martin Nordholts

10/06/2019, 6:24 AM
Why is it necessary to have a
Observer
prefix in the second line below in order for SAM conversion to work, but not in the first line? The last parameter has identical declarations in these two cases.
MutableLiveData<String>().observeForever({  })        // No 'Observer' prefix necessary
    MutableLiveData<String>().observe(this, Observer {  })        // 'Observer' prefix necessary!

    // Java declarations
    public void observeForever(@NonNull Observer<? super T> observer) {
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
i

ilya.gorbunov

10/06/2019, 4:36 PM
Currently SAM conversion for a function works by providing a synthetic overload where all SAM interfaces are replaced with the corresponding functional types. Looks like
LifecycleOwner
is also a SAM interface, so we've got two overloads here: the original one, where both owner and observer are interfaces, and the synthetic one, where both owner and observer are functional types. Passing
this
instance to
owner
selects the origninal one, so you have to pass
observer
not as a function, but as an interface either.
m

Martin Nordholts

10/06/2019, 4:44 PM
Thanks for explaining, but I don’t fully understand your answer and would like to learn more, but https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions didn’t quite help me out here. For example, I wonder what “synthetic overload” is. Is there somewhere I can read more about this?
Or doyou mean synthetic method overload on
MutableLiveData
? I.e. that the compiler pretends that there is a version of
observe
that takes proper Kotlin functions as arguments?
i

ilya.gorbunov

10/06/2019, 4:51 PM
Yes, it's an overload of
observe
function. For example like here:
m

Martin Nordholts

10/06/2019, 4:51 PM
Aha now I think I get it. Couldn’t the compiler make 3 synthetic overloads in this case then? I.e. observe(interface, interface) observe(function, function) observe(function, interface) observe(interface, function)? Although I guess that’s O(n^2)-ish… But in practice it should work most of the time probably.
i

ilya.gorbunov

10/06/2019, 4:52 PM
More likely O(2^n)-ish, which is much worse
m

Martin Nordholts

10/06/2019, 4:53 PM
Yes you’re right, it would be O(2^n)-ish
Anyway, now I fully understand what happens. Thanks a lot for explaining.
i

ilya.gorbunov

10/06/2019, 4:56 PM
AFAIK, the new inference has another approach to this that doesn't rely on synthetic overloads and allows to apply the conversion to an each argument individually.
👍 1