Vince
Vince

Reputation: 15146

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 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. 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.

Question

How do I properly call the doSomething function from a Java project?

Upvotes: 2

Views: 1246

Answers (2)

Jakob Bowyer
Jakob Bowyer

Reputation: 34698

Using the following code

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

And the following java

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

It works just fine.

Upvotes: 3

Connor Spencer Harries
Connor Spencer Harries

Reputation: 878

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.

[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:

<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. 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.

Without the workarounds mentioned I couldn't compile it either.

Edit: It appears Gradle requires no workaround as demonstrated here.

Upvotes: 3

Related Questions