如何使用带有通用接口和其他参数的构造函数在Kotlin中创建对象

时间:2018-07-18 12:21:34

标签: kotlin assertj

我在Kotlin中使用AssertJ,并尝试使用AssertJ-Condition。

构造函数的定义如下:

Condition(Predicate<T> predicate, String description, Object... args)

请参见http://joel-costigliola.github.io/assertj/core-8/api/org/assertj/core/api/Condition.html

但是我不能正确地创建作品。我尝试了以下方法(为简便起见,省略了更多内容):

Condition<File>({ it.name.startsWith("functional_questions") }, "Description")

出现此错误:enter image description here

Condition<File>({ file -> file.name.startsWith("functional_questions") }, "Description")

出现此错误: enter image description here

我如何成功?

2 个答案:

答案 0 :(得分:2)

我能想到的最好的方法是:

Condition<File>(Predicate<File> { file -> file.name.startsWith("functional_questions") }, "description")

编辑:您的代码不起作用,因为默认情况下Kotlin lambda不实现所需的接口。如果运行以下代码:

val predicate1 = { file: File -> file.name.startsWith("functional_questions") }
val predicate2 = Predicate<File> { file -> file.name.startsWith("functional_questions") }

predicate1::class.java.interfaces.forEach { println(it) }
println() //new line to separate outputs
predicate2::class.java.interfaces.forEach { println(it) }

您将获得以下输出:

interface kotlin.jvm.functions.Function1

interface java.util.function.Predicate

区别很明显。

答案 1 :(得分:1)

据我所知,

AssertJ对Kotlin没有特殊支持,因此仅支持Java谓词。

在此处查看有关为什么我们不能将kotlin lambda作为功能接口传递的更多信息:https://stackoverflow.com/a/33610615/5335131

有两种方法可以使其起作用:

@Test fun assertj() {
    Condition<File>(Predicate { it.name.startsWith("functional_questions") }, "Description")
    condition<File>("Description") { it.name.startsWith("functional_questions") }
}

fun <T> condition(description: String, predicate: (T) -> Boolean) =
    Condition<T>(Predicate<T> { predicate(it) }, description)

首先使用显式谓词,其次使用辅助函数。