scala中的隐式json转换器在运行时为null
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scala中的隐式json转换器在运行时为null相关的知识,希望对你有一定的参考价值。
使用了play框架我有一个case类的文件(在Project中有聚合Task。很重要)就像
case class Project (var tasks: Map[String, Task])
case class Task (var activities: Map[String, String])
并在另一个文件特征中进行转换
trait JsonConverters {
implicit val projectWrite: OWrites[Project] = Json.writes[Project]
implicit val projectRead: Reads[Project] = Json.reads[Project]
implicit val taskWrite: OWrites[Task] = Json.writes[Task]
implicit val taskRead: Reads[Task] = Json.reads[Task]
}
object JsonConverters extends JsonConverters
在我的服务类中
import support.JsonConverters._
class Service {
def someMethod(json: String) = {
val obj = Json.parse(json).as[Map[String, Project]]
}
}
在编译时一切都很好。但在json解析中我得到了json库中的NPE(play.api.libs.json.DefaultReads#mapReads
)
implicit def mapReads[K, V](k: String => JsResult[K])(implicit fmtv: Reads[V]): Reads[Map[K, V]] = Reads[Map[K, V]] {
任务类的implicit fmtv: Reads[V]
为null(对于Project都很好)
我认为这是因为在.as[Map[String, Project]
中只指定了Project类,而不是Task。但事实并非如此
我找到了两个不同的解决方案来解决这个问题,但两者对我来说都很难看
1)使用case类在同一个文件中声明所有隐式转换器。但我希望将所有转换器都放在分开的文件中。这个解决方案不适合我
2)在qazxsw poi中使用lazy mod声明对Task的隐式
trait JsonConverters
它工作正常,看起来很好。但是我不明白为什么没有单独的特质懒惰它不起作用?谁有人形容?或建议另一种解决方案
平凡变量(trait JsonConverter {
implicit val projectWrite: OWrites[Project] = Json.writes[Project]
implicit val projectRead: Reads[Project] = Json.reads[Project]
implicit lazy val taskWrite: OWrites[Task] = Json.writes[Task]
implicit lazy val taskRead: Reads[Task] = Json.reads[Task]
}
)和惰性变量(val
)的初始化顺序是不同的。
lazy val
按照文件中描述的顺序进行初始化。
val
是在首次访问时初始化的。
在你的情况下,lazy val
包含一个Project
所以Task
需要初始化的projectRead
完成。
在你的代码中,没有taskRead
,lazy
在projectRead
之前宣布,所以当taskRead
需要时,taskRead
仍然是null
。这就是你获得NPE的原因。
仍然,编译器可以找到隐式projectRead
并且不会引发错误。
您对taskRead
的修复有效,因为lazy
现在在首次访问时初始化。现在,当taskRead
要求时,taskRead
初始化。 NPE消失了。
您可以通过切换声明顺序来实现相同的修复:
projectRead
以上是关于scala中的隐式json转换器在运行时为null的主要内容,如果未能解决你的问题,请参考以下文章