Java – when the first parameter is a class with a method, you cannot replace the SAM constructor with lambda

I'm confused about the SAM constructor. I have this Java class:

public class TestSam<T> {

    public void observe(ZeroMethods zero,Observer<T> observer) {
    }

    public void observe(OneMethod one,Observer<T> observer) {
    }

    public void observe(TwoMethods two,Observer<T> observer) {
    }

    public interface Observer<T> {
        void onChanged(@Nullable T t);
    }

    public interface ZeroMethods {
    }

    public interface OneMethod {
        First getFirst();
    }

    public interface TwoMethods {
        First getFirst();

        Second getSecond();
    }

    public interface First {
    }

    public interface Second {
    }
}

And this kotlin Code:

fun testSam(
        test: TestSam<String>,zero: TestSam.ZeroMethods,one: TestSam.OneMethod,two: TestSam.TwoMethods
) {
    test.observe(zero) { println("onChanged $it") } // 1. compiles
    test.observe(zero,TestSam.Observer { println("onChanged $it") }) // 2. Redundant SAM-constructor

    test.observe(one) { println("onChanged $it") } // 3. doesn't compile
    test.observe({ one.first }) { println("onChanged $it") } // 4. compiles
    test.observe(one,TestSam.Observer { println("onChanged $it") }) // 5. compiles

    test.observe(two) { println("onChanged $it") } // 6. compiles
    test.observe(two,TestSam.Observer { println("onChanged $it") }) // 7. Redundant SAM-constructor
}

What kind of deal is this? Why can't kotlin figure out 3 (and provide special variant 4.), But deal with all other situations?

The basic principle of this code is livedata < T > in Android Observe (lifecycle owner owner, observer < T > observer) method, where lifecycle owner has a method getlifecycle()

Solution

I found a rule in the compiler: if Java method calls require Sam interfaces types, you can replace them with Lambdas (or functions), but either all these parameters or none

So, you have a method: public void observe (onemethod one, observer < T > observer) Both parameters are Sam candidates You can call: observer (object1, object2) or observer (function1, function2)

But not: the observer (object1, function2) is not the observer (function1, object2)

The same behavior occurs even with three or more parameters The reason for this is the technical difficulty in compiler design

Sorry, if I'm not very clear, my English is not very good

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>