ответил в комментариях в Android Good Reads, но решил и тут написать, вдруг кому-то будет интересно
допустим, у нас есть такой Java-класс
public class SomeJavaClass {
interface Listener {
void onEvent(String event);
}
private HashSet<Listener> listeners = new HashSet<>();
void addListener(Listener listener) {
listeners.add(listener);
}
void removeListener(Listener listener) {
listeners.remove(listener);
}
}
и такой Kotlin-класс
class SomeKotlinClass {
private val eventListenerLambda = { eventId: String ->
println(eventId)
}
fun testLambdas(someJavaClass: SomeJavaClass) {
someJavaClass.addListener(eventListenerLambda)
someJavaClass.removeListener(eventListenerLambda)
}
}
чтобы передать лямбду типа
(String) -> Unit в качестве параметра типа Listener, компилятор либо использует method reference, либо, когда Java 6, заворачивает в адаптер, и в обоих случаях инстанс итогового Listener каждый раз получается разный
public final class SomeKotlinClass {
@NotNull
private final Function1 eventListenerLambda = SomeKotlinClass::eventListenerLambda$lambda$0;
public static final int $stable;
public final void testLambdas(@NotNull SomeJavaClass someJavaClass) {
Intrinsics.checkNotNullParameter(someJavaClass, "someJavaClass");
Function1 var2 = this.eventListenerLambda;
someJavaClass.addListener(SomeKotlinClass::testLambdas$lambda$1);
var2 = this.eventListenerLambda;
someJavaClass.removeListener(SomeKotlinClass::testLambdas$lambda$2);
}
private static final Unit eventListenerLambda$lambda$0(String eventId) {
Intrinsics.checkNotNullParameter(eventId, "eventId");
System.out.println(eventId);
return Unit.INSTANCE;
}
private static final void testLambdas$lambda$1(Function1 $tmp0, String event) {
$tmp0.invoke(event);
}
private static final void testLambdas$lambda$2(Function1 $tmp0, String event) {
$tmp0.invoke(event);
}
}
и если запустить, можно увидеть, что после выполнения
someJavaClass.removeListener(eventListenerLambda) содержимое listeners не изменитсянапишите в комменты, кому это было очевидно!