Jinq in Kotlin - 如何将lambda转换为java SerializedLambda?

时间:2016-10-15 21:37:58

标签: kotlin kotlin-interop

我可以在Kotlin中使用可序列化的lambda吗?我正在尝试使用Kotlin的Jinq库,但它需要可序列化的lambdas。是否有任何语法可以实现?

更新

我的代码:

var temp=anyDao.streamAll(Task::class.java)
   .where<Exception,Task> { t->t.taskStatus== TaskStatus.accepted }
   .collect(Collectors.toList<Task>());

我收到此错误:

Caused by: java.lang.IllegalArgumentException: 
Could not extract code from lambda. 
This error sometimes occurs because your lambda references objects that aren't Serializable.

lambda中引用的所有对象都是可序列化的(代码在java中没有错误)。

更新2

调试后,似乎kotlin lambda没有被翻译成java.lang.invoke.SerializedLambda,这是Jinq从中获取信息所必需的。所以问题是如何将其转换为SerializedLambda。

2 个答案:

答案 0 :(得分:0)

我没有Jinq的经验,但是根据GitHub中的实现以及我在Kotlin中使用Java库的经验。

参考:https://github.com/my2iu/Jinq/blob/master/api/src/org/jinq/orm/stream/JinqStream.java

您可以随时回退使用Kotlin中的本机Java接口。

var temp = anyDao.streamAll(Task::class.java)
   .where( JinqStream.Where<Task,Exception> { t -> t.taskStatus == TaskStatus.accepted } )
   .collect(Collectors.toList<Task>());

 // Alternatively, You you can import the interface first
 import org.jinq.orm.stream.JinqStream.*

  ... 

  // then you can use Where instead of JinqStream.Where
  var temp = anyDao.streamAll(Task::class.java)
       .where(Where<Task,Exception> { t -> t.taskStatus == TaskStatus.accepted } )
       .collect(Collectors.toList<Task>());

或制作自定义扩展程序以包装实现

fun JinqStream<T>.where(f: (T) -> Boolean): JinqStream<T> {
  return this.where(JinqStream.Where<T,Exception> { f(it) })
}

免责声明:以上代码尚未经过测试。

答案 1 :(得分:0)

我是Jinq的制造商。我还没有时间查看Kotlin支持,但是根据您的描述,我假设Kotlin将其lambda编译为实际的类或其他内容。因此,Jinq可能需要一些特殊的代码来破解开放的Kotlin lambda,并且还可能需要特殊的代码来处理生成的代码中的任何异常Kotlin-ism。 Jinq应该能够处理它,因为先前已对其进行了改进以处理Scala lambda。

如果您在Jinq github上提出有关此问题的信息,以及一个小的Kotlin示例(以源文件和.class文件的形式),那么我可以快速浏览一下可能涉及的内容。如果很小,我可以进行更改。不幸的是,如果看起来需要做很多工作,我认为我真的没有理由为在Jinq中添加Kotlin支持投入大量资源。