Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Moshi parse integers, longs as Double?

Tags:

kotlin

moshi

I'm trying to parse a not very well designed api's json using Moshi + kotlin. For some reasons it parses numbers like 71 as Double.

The 3rd party api has a list of objects that could either look like: {"foo":[[1234567000,12]]} // long, int or {"foo":[[1234567000,"string",0,2]]} // long, string, int, int

Because of the 3rd party api I have the following kotlin class:

@JsonClass(generateAdapter = true)
class D {
    var foo: List<Any> // I use Any because it can be either String or Int or Long
}

and in my code I do something like:

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]

but for some reason Moshi converts the integers in the json string into Doubles instead of Int or Long. How could I fix it?

like image 205
Gavriel Avatar asked Sep 02 '25 16:09

Gavriel


1 Answers

JSON number type makes no distinction between integer and floating-point

Fundamental idea behind any JSON parsing library is to parse JSON into certain type, if that type has properties of type integer then parsing library will try to convert JSON number type to integer, but you are parsing json to Any, which essentially tells moshi to take a guess as to the type of the Object.

Since JSON doesn't distinguish between integer and floating point fields moshi defaults to Float/Double for numeric fields when parsing to Any.

And the issue here is in the API, it should not return different type values for same query. at the very least there should be an indication as to the type of data. What happens if you receive a string value which actually looks like a number?

like image 91
mightyWOZ Avatar answered Sep 04 '25 07:09

mightyWOZ