简体   繁体   English

Kotlin在Java项目中的高阶函数

[英]Kotlin's Higher-Order Functions in Java project

I have a function that has a function type as a formal parameter: 我有一个函数类型作为形式参数:

fun doSomething(code: () -> Boolean) = false //package function in TestKt.class

I've tried calling it in Java, passing in a lambda: 我试过用Java调用它,传入一个lambda:

//Java class, in Java project
class Demo {
    public static void main(String[] args) {
        TestKt.doSomething(() -> false);
    }
}

But I get the error: 但我得到错误:

Cannot infer functional interface type 无法推断出功能界面类型

It works when the Java class is in a Kotlin project, but not in a Java project. 它适用于Java类在Kotlin项目中,但不在Java项目中。 I haven't had problems with anything else while using classes from Kotlin in my Java project, such as using kotlin methods typed with kotlin.Boolean and working with vararg parameters. 在我的Java项目中使用Kotlin中的类时,我没有遇到任何其他问题,例如使用kotlin方法键入kotlin.Boolean并使用vararg参数。

Question

How do I properly call the doSomething function from a Java project? 如何从Java项目中正确调用doSomething函数?

I threw your code into a module in my project and it built just fine, though this may be a side effect of me using multiple modules as the kotlin is always compiled to java before the java projects can touch it. 我把你的代码扔进了我项目中的一个模块,它构建得很好,虽然这可能是我使用多个模块的副作用,因为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

If you are using maven (with mixed kotlin and java in a single module) then you may be required to add the following to your POM: 如果您使用maven(在单个模块中使用混合kotlin和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>

I'm not sure if such a solution exists for gradle. 我不确定这种解决方案是否适用于gradle。 If you don't use a dependency manager then you should be able to work around this by invoking the kotlin compiler and then javac . 如果你不使用依赖管理器,那么你应该能够通过调用kotlin编译器然后调用javac来解决这个问题。

Without the workarounds mentioned I couldn't compile it either. 如果没有提到的解决方法,我也无法编译它。

Edit: It appears Gradle requires no workaround as demonstrated here . 编辑:看来摇篮不需要任何解决方法,因为证明了这里

Using the following code 使用以下代码

fun doSomething(method: () -> Boolean) = method()

And the following java 和以下java一样

public class Test {
    public static void main(String[] args) {
        System.out.println(MainKt.doSomething(() -> true));
    }
}

It works just fine. 它工作得很好。

The environment must support the Kotlin API. 环境必须支持Kotlin API。

If the environment has restrictions on 3rd party libraries, and does not support the Kotlin API, you will not be able to use Kotlin in that environment. 如果环境对第三方库有限制,并且不支持Kotlin API,则无法在该环境中使用Kotlin。


I came back to this issue and finally found the problem. 我回到这个问题,终于找到了问题。 The environment I was working restricted third-party libraries, which prevented me from using the Kotlin API. 我工作的环境限制了第三方库,这使我无法使用Kotlin API。

It's due to Kotlin using it's own types for primitives (such as Boolean ). 这是由于Kotlin使用它自己的基元类型(如Boolean )。 At first, I thought those types would be compiled into Java primitive wrappers to ensure full interop. 起初,我认为这些类型将被编译成Java原始包装器以确保完全互操作。 But apparently it still uses the Boolean from the Kotlin API. 但显然它仍然使用Kotlin API中的Boolean

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM