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