У меня есть функция, которая имеет тип функции как формальный параметр:
fun doSomething(code: () -> Boolean) = false //package function in TestKt.class
Я пробовал называть его на Java, проходя в лямбда:
//Java class, in Java project class Demo { public static void main(String[] args) { TestKt.doSomething(() -> false); } }
Но я получаю сообщение об ошибке:
Невозможно определить тип функционального интерфейса
Он работает, когда класс Java находится в проекте Kotlin, но не в проекте Java. У меня не было проблем с чем-либо еще при использовании классов из Kotlin в моем проекте Java, например, с использованием методов kotlin, набранных с помощью kotlin.Boolean
и работы с параметрами vararg
.
Вопрос
Как правильно вызвать функцию doSomething
из проекта Java?
Я бросил ваш код в модуль в моем проекте, и он построил просто отлично, хотя это может быть побочным эффектом для меня, используя несколько модулей, поскольку kotlin всегда скомпилирован в java, прежде чем проекты java могут коснуться его.
[INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] mesh-parent ....................................... SUCCESS [1.718s] [INFO] mesh-common ....................................... SUCCESS [13.141s] [INFO] mesh-controller ................................... SUCCESS [8.217s] [INFO] java-so-project ................................... SUCCESS [1.121s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 24.558s [INFO] Finished at: Thu Jan 07 20:21:30 GMT 2016 [INFO] Final Memory: 55M/341M [INFO] ------------------------------------------------------------------------ Process finished with exit code 0
Если вы используете maven (со смешанным котлином и java в одном модуле), вам может потребоваться добавить следующее к вашему POM:
<plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <executions> <execution> <phase>process-sources</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <phase>process-test-sources</phase> <goals> <goal>test-compile</goal> </goals> </execution> </executions> </plugin>
Я не уверен, существует ли такое решение для градиента. Если вы не используете менеджер зависимостей, тогда вы сможете обойти это, вызывая компилятор kotlin, а затем javac
.
Без обходных решений я тоже не смог его скомпилировать.
Edit: Похоже, что Gradle не требует обходного пути, как показано здесь .
Используя следующий код
fun doSomething(method: () -> Boolean) = method()
И следующая java
public class Test { public static void main(String[] args) { System.out.println(MainKt.doSomething(() -> true)); } }
Он работает отлично.
Окружающая среда должна поддерживать API Kotlin.
Если среда имеет ограничения на сторонние библиотеки и не поддерживает API Kotlin, вы не сможете использовать Kotlin в этой среде.
Я вернулся к этой проблеме и, наконец, нашел проблему. В среде, в которой я работал, были ограничены сторонние библиотеки, что помешало мне использовать API Kotlin.
Это связано с тем, что Котлин использовал свои собственные типы для примитивов (например, Boolean
). Сначала я думал, что эти типы будут скомпилированы в примитивные оболочки Java для обеспечения полного взаимодействия. Но, по-видимому, он по-прежнему использует Boolean
из API Kotlin.