I’m puzzled over SAM constructors, 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's the deal here? Why can't Kotlin figure out 3. (and provides the special variant 4.), but handles all other cases?
The rationale for this code is LiveData<T>.observe(LifecycleOwner owner, Observer<T> observer) method in Android, where LifecycleOwner has one method getLifecycle().