Je suis perplexe sur les constructeurs SAM, j'ai cette classe Java:ne peut pas remplacer constructeur SAM avec lambda quand le premier argument est une classe avec une méthode
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 {
}
}
Et ce code Kotlin:
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
}
Quelle est la situation ici? Pourquoi Kotlin ne peut pas comprendre 3. (et fournit la variante spéciale 4.), mais gère tous les autres cas?
La justification de ce code est procédé LiveData<T>.observe(LifecycleOwner owner, Observer<T> observer)
dans les applications où LifecycleOwner
a une méthode getLifecycle()
.
Pouvez-vous ajouter un lien vers le code source du compilateur? (Ou à une spécification où cela est expliqué?) (Ou avez-vous trouvé la réponse en l'essayant?) – Marco13
Je pense que ce n'est pas vraiment documenté, juste essayé moi-même. Pour plus de précision, il est préférable de demander aux développeurs Kotlin. L'un d'entre eux m'a dit ce qu'il y avait un problème dans bug tracker pour cela. – Beholder
Oh, je pense que j'ai compris. Le problème est que mon 'OneMethod' et' LifecycleOwner' d'Android sont des interfaces SAM. Dommage que ce soit seulement par accident, vraiment, parce que je doute que 'LifecycleOwner' soit utilisé comme' Runnable' est utilisé par exemple, nous ne définirions jamais de classes anonymes pour cela en Java, l'interface est implémentée par 'AppCompatActivity' classe de base. – arekolek