为什么 Moshi 将整数解析为 Double?
Why does Moshi parse integers, longs as Double?
我正在尝试使用 Moshi + kotlin 解析设计不是很好的 api 的 json。由于某些原因,它将 71 之类的数字解析为 Double。
第 3 方 api 有一个对象列表,可能如下所示:
{"foo":[[1234567000,12]]} // 长整型
或者
{"foo":[[1234567000,"string",0,2]]} // long, string, int, int
因为第 3 方 api 我有以下 kotlin class:
@JsonClass(generateAdapter = true)
class D {
var foo: List<Any> // I use Any because it can be either String or Int or Long
}
在我的代码中我做了类似的事情:
val moshi = Moshi.Builder().build()
val adapter = moshi.adapter(D::class.java)
var D d = adapter.fromJson("{\"foo\":[[1234567000,\"string\",0,2]]}")
var index = d.foo[2]
var value : Long = 0
// here I get an error: ClassCastException: java.lang.Double cannot be cast to java.lang.Long
value = d.foo[index]
但出于某种原因,Moshi 将 json 字符串中的整数转换为 Double,而不是 Int 或 Long。我该如何解决?
我不确定这是否是最简单的方法,但它有效:
class AnyAdapter {
@FromJson fun fromJson(str: String): Any {
var any: Any
try {
any = Integer.parseInt(str)
} catch (e: NumberFormatException) {
try {
any = java.lang.Long.parseLong(str)
} catch (e: NumberFormatException) {
try {
any = java.lang.Double.parseDouble(str)
} catch (e: NumberFormatException) {
any = str
}
}
}
return any
}
}
val moshi = Moshi.Builder()
.add(AnyAdapter())
.build()
val adapter = moshi.adapter(D::class.java)
var D d = adapter.fromJson("{\"foo\":[[1234567000,\"string\",0,2.0]]}")
var l : Long = d.foo[0] as Long
var s : String = d.foo[1] as String
var i : Int = d.foo[2] as Int
var dd : Double = d.foo[3] as Double
JSON数字类型不区分整数和浮点数
任何JSON解析库背后的基本思想是将JSON解析为某种类型,如果该类型具有整数类型的属性,那么解析库将尝试转换JSON数字类型为整数,但您正在将 json 解析为 Any,这实际上告诉 moshi 猜测对象的类型。
因为 JSON 不区分整数和浮点字段 moshi 在解析为 Any 时默认为数字字段 Float/Double。
这里的问题出在 API,它不应该 return 同一查询的不同类型值。至少应该说明数据的类型。 如果您收到一个实际上看起来像数字的字符串值会怎样?
我正在尝试使用 Moshi + kotlin 解析设计不是很好的 api 的 json。由于某些原因,它将 71 之类的数字解析为 Double。
第 3 方 api 有一个对象列表,可能如下所示: {"foo":[[1234567000,12]]} // 长整型 或者 {"foo":[[1234567000,"string",0,2]]} // long, string, int, int
因为第 3 方 api 我有以下 kotlin class:
@JsonClass(generateAdapter = true)
class D {
var foo: List<Any> // I use Any because it can be either String or Int or Long
}
在我的代码中我做了类似的事情:
val moshi = Moshi.Builder().build()
val adapter = moshi.adapter(D::class.java)
var D d = adapter.fromJson("{\"foo\":[[1234567000,\"string\",0,2]]}")
var index = d.foo[2]
var value : Long = 0
// here I get an error: ClassCastException: java.lang.Double cannot be cast to java.lang.Long
value = d.foo[index]
但出于某种原因,Moshi 将 json 字符串中的整数转换为 Double,而不是 Int 或 Long。我该如何解决?
我不确定这是否是最简单的方法,但它有效:
class AnyAdapter {
@FromJson fun fromJson(str: String): Any {
var any: Any
try {
any = Integer.parseInt(str)
} catch (e: NumberFormatException) {
try {
any = java.lang.Long.parseLong(str)
} catch (e: NumberFormatException) {
try {
any = java.lang.Double.parseDouble(str)
} catch (e: NumberFormatException) {
any = str
}
}
}
return any
}
}
val moshi = Moshi.Builder()
.add(AnyAdapter())
.build()
val adapter = moshi.adapter(D::class.java)
var D d = adapter.fromJson("{\"foo\":[[1234567000,\"string\",0,2.0]]}")
var l : Long = d.foo[0] as Long
var s : String = d.foo[1] as String
var i : Int = d.foo[2] as Int
var dd : Double = d.foo[3] as Double
JSON数字类型不区分整数和浮点数
任何JSON解析库背后的基本思想是将JSON解析为某种类型,如果该类型具有整数类型的属性,那么解析库将尝试转换JSON数字类型为整数,但您正在将 json 解析为 Any,这实际上告诉 moshi 猜测对象的类型。
因为 JSON 不区分整数和浮点字段 moshi 在解析为 Any 时默认为数字字段 Float/Double。
这里的问题出在 API,它不应该 return 同一查询的不同类型值。至少应该说明数据的类型。 如果您收到一个实际上看起来像数字的字符串值会怎样?