Как kotlin делает setOnClickListener принимать функции как параметр

В kotlin мы можем использовать setOnClickListener() следующим образом:

 view.setOnClickListener { println("Hello") } 

Но если я определяю свой собственный интерфейс, я могу передать анонимный объект следующим образом:

 obj.setMyListener(object: MyListener() { ... }) 

Мне просто интересно, как они делают setOnClickListener() принимают функцию, а не анонимный объект.

Согласно документации Kotlin о взаимодействии Java , для функционального интерфейса, определенного на Java, вы можете использовать преобразование SAM.

Как и Java 8, Kotlin поддерживает конверсии SAM. Это означает, что литералы функции Kotlin могут быть автоматически преобразованы в реализации интерфейсов Java с помощью одного метода, отличного от метода по умолчанию, если типы параметров метода интерфейса соответствуют типам параметров функции Kotlin.

 val runnable = Runnable { println("This runs in a runnable") } val executor = ThreadPoolExecutor() // Java signature: void execute(Runnable command) executor.execute { println("This runs in a thread pool") } 

Тем не менее, Kotlin имеет функциональные типы, поэтому преобразование SAM не работает для интерфейсов, определенных в Kotlin:

Также обратите внимание, что эта функция работает только для Java interop; поскольку Kotlin имеет собственные типы функций, автоматическое преобразование функций в реализации интерфейсов Kotlin не является необходимым и поэтому не поддерживается.


Возможные решения:

  1. Определите интерфейс в Java. Полезно, если это библиотека / код, который может использоваться из Java-кода.
  2. Чтобы метод получил функцию в качестве аргумента:

     // Example listener receives a bool and return unit. fun setMyListener(listener: (isChecked: Bool) -> Unit) { ... } // Usage: obj.setMyListener { isChecked -> } 
  3. Использовать псевдоним типа (поддерживается только в Kotlin 1.1+):

     typealias MyListener = (Bool) -> Unit fun setMyListener(listener: MyListener) { ... } 
Intereting Posts
Доступ к TextView в пользовательском классе в Котлине Kotlin падает на Android, когда выбранный вид элемента равен нулю Hibernate игнорирует «ленивый» тип выборки и сразу загружает свойства Номер Android с RxJava обрабатывает пустой результат запроса только классы разрешены в левой части литерала класса при использовании Mockito и kotlin Dagger2 не генерирует классы кинжалов Почему приложение Spring Boot не может найти основную страницу? Котлин назначает делегата после объявления переменной Почему Kotlin с Spring MVC JSON возвращает пустой объект? Котлин – Функции более высокого порядка и несоответствие типов Как создать неизменный список в Kotlin, который также является неизменным списком в Java? Anko вид из класса Котлин: заявление Лямбде Как показать голландский месяц с использованием Joda DateTime Текстовый объект объекта Kotlin, реализующий дикий кардочесальный, саморегуляторный общий интерфейс