java - 如何在 Scala 中从 JSON 解析通用类参数?

标签 java json scala generics json4s

我有一个通用的 getter 特征

trait Getter[A] {
  def get: A
}

我想将 JSON 解析为实现此特征的对象列表。两个这样的实现:

case class CoalesceGetter[A](getters: List[Getter[String]]) extends Getter[A] {
  override def get: A = getters.map(_.get).find(_ != null).orNull
}

case class AsnGetter(ipGetter: Getter[String]) extends Getter[Long] {
  override def get: Long = 99L // dummy function
}

我想根据名为 function 的属性将 JSON 解析为正确的 Getter 类,该属性对应于该类和对应的 type对于需要泛型的 getter 来说,为泛型类型(这两个属性都是我正在解析的 json blob 中的字符串)。我看过 json4s 的自定义序列化器,但不知道如何使用泛型。如有任何帮助,我们将不胜感激!

最佳答案

首先,我认为使用类型参数对类进行 jsonify 不是一个好主意。我认为定义与 json 对象直接等效的非类型(大小写)类,并使用许多库提供的标准读/写 json 是一个更好的设计。

但是,为了回答你的问题,我想返回另一个问题:你将如何“手动”做到这一点? IE。您将如何使用不同的 A 来编写和读取不同的 CoalesceGetter[A]?

这里有一个建议:将类型 arg 放入 json 字段中:

"ofInt":   {"type-arg":"Int", "getters":[ ... list of getters in json ...]},
"ofDouble":{"type-arg":"Double", "getters":[ ... list of getters in json ...]}

现在,如果您编写阅读器,知道类型参数“Int”和“Double”(它们是字符串!),您将如何实例化 2 个 ofInt 和 ofDouble。

我看到两种解决方案:

1) 要么你有一个 arg-type string => 实际 scala 类型的硬编码映射

 argType match{
   case "Int"    => new CoalesceGetter[Int](...)
   case "Double" => new CoalesceGetter[Double](...)
 }

2) 或者您将通用类型作为字符串值存储并读取在 arg 类型字符串中,例如 java Class.forName(例如,请参阅 [ https://stackoverflow.com/a/7495850/1206998] )。但恕我直言,这是一个非常非常糟糕的主意。

(注意:如果您想序列化任何对象只是为了稍后重新加载或在另一台计算机上重新加载,请不要使用 json,而应使用专用序列化,例如 Spark 使用的 Java 序列化或 kryo)

关于java - 如何在 Scala 中从 JSON 解析通用类参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48756491/

相关文章:

ajax - Extjs 自定义阅读器

json - jq 加入公共(public)键

scala - Spock mock Akka 的 ActorRef

Scala 编译错误 : not found: type _$1

java - Retrofit 2在请求数据中命名变量时添加java类名

java - @JsonSerialize 与泛型

Java列表检查元素是否重复并标记它

Java,Spring "saveOrUpdate",DAO 中的 "update"

javascript - jQuery/JavaScript 循环遍历 json 数据结果

scala - 案例类修改和设计通用方式