java.lang.Integer cannot be cast to java.lang.Long
Asked Answered
P

6

36

I'm supposed to receive long integer in my web service.

long ipInt = (long) obj.get("ipInt");

When I test my program and put ipInt value = 2886872928, it give me success. However, when I test my program and put ipInt value = 167844168, it give me error :

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long

The error is point to the above code.

FYI, my data is in JSON format :

{
    "uuID": "user001",
    "ipInt": 16744168,
    "latiTude": 0,
    "longiTude": 0,
}

Is there any suggestion so that I can ensure my code able to receive both ipInteger value?

Pinnate answered 23/9, 2019 at 6:46 Comment(4)
What's the type of obj? How is it created and populated?Commensal
Instead of casting the int value try using Long.parseLong(int)Fatherhood
@SherwinObciana: Given that obj.get("ipInt") apparently returns Integer, I can't see how that would work.Scevor
Some JSON libs allow you to force integer numbers to be parsed as long, which would solve your issue altogether. Here is a solution for jackson (if that's what you're using)Epigraphy
S
58

Both Integer and Long are subclasses of Number, so I suspect you can use:

long ipInt = ((Number) obj.get("ipInt")).longValue();

That should work whether the value returned by obj.get("ipInt") is an Integer reference or a Long reference. It has the downside that it will also silently continue if ipInt has been specified as a floating point number (e.g. "ipInt": 1.5) in the JSON, where you might want to throw an exception instead.

You could use instanceof instead to check for Long and Integer specifically, but it would be pretty ugly.

Scevor answered 23/9, 2019 at 6:48 Comment(3)
I happen to find it more resilient, with regards to "ill-formed" 1.5 or 1., if we assume the contract is that ipInt is supposed to be an integer. It will "succeed silently" instead of "crashing explicitly".Zymo
@Matthieu: Do you mean you prefer a scenario where invalid data is silently passed through the system, with data loss? I personally prefer invalid data to be caught as early as possible with a hard error. If some code tries to update my bank balance with a non-number, I'd rather that system crashed than set it to 0 :)Scevor
Dear God, I get you ;) I guess it mostly depends on the scenario: when you deal with money, hard crash is obviously preferred. But I have some processes that should (almost) never stop, and hence have to continue with last-correct configuration. Of course, in that case, we should catch the exception and at least log it. Ok, as I'm writing that, I'm getting convinced. Thanks :)Zymo
Z
8

We don't know what obj.get() returns so it's hard to say precisely, but when I use such methods that return Number subclasses, I find it safer to cast it to Number and call the appropriate xxxValue(), rather than letting the auto-unboxing throw the ClassCastException:

long ipInt = ((Number)obj.get("ipInt")).longValue();

That way, you're doing explicit unboxing to a long, and are able to cope with data that could include a ., which would return a Float or Double instead.

Zymo answered 23/9, 2019 at 6:56 Comment(1)
I mark the date: wrote (almost) the same answer than Jon Skeet with (almost) 1000 times less rep ;)Zymo
N
3
Long.valueOf(jo.get("ipInt").toString());

Is ok.

Norrie answered 30/6, 2020 at 6:50 Comment(0)
A
2

in kotlin I simply use this:

val myInt: Int = 10
val myLong = myInt.toLong()
Amongst answered 26/10, 2020 at 8:1 Comment(0)
B
0

You mention the current approach works when you provide a value outside the range of integer, but fails when you are within the integer range. That is an odd behavior for an API, because it seems you need to check the return type yourself. You can do that. The usual way is with instanceof. Something like,

long ipInt;
Object o = obj.get("ipInt");
if (o instanceof Integer) {
    ipInt = ((Integer) o).intValue();
} else if (o instanceof Long) {
    ipInt = ((Long) o).longValue();
}
Busk answered 23/9, 2019 at 6:55 Comment(0)
N
0
public static void main(String[] args) {
    JSONObject jo = JSON.parseObject(
        "{    \"uuID\": \"user001\",    \"ipInt\": 16744168,    \"latiTude\": 0,    \"longiTude\": 0}");
    System.out.println(jo);
    long sellerId1 =  Long.valueOf(jo.get("ipInt").toString());
    //Long sellerId1 = (long)jo.get("ipInt");
    System.out.println(sellerId1);
}
Norrie answered 30/6, 2020 at 6:57 Comment(2)
Please explain what the code does and why it answers the question.Zymo
Some cases this works. Thanks for this!Eolic

© 2022 - 2024 — McMap. All rights reserved.