java.lang.Integer无法转换为java.lang.Long。

34

我的网络服务应该接收长整型数。

long ipInt = (long) obj.get("ipInt");
当我测试我的程序并将ipInt值设为2886872928时,它显示成功。 然而,当我测试我的程序并将ipInt值设为167844168时,它显示错误:
java.lang.ClassCastException: java.lang.Integer无法转换为java.lang.Long
该错误指向上述代码。
FYI,我的数据以JSON格式存储:
{
    "uuID": "user001",
    "ipInt": 16744168,
    "latiTude": 0,
    "longiTude": 0,
}

有什么建议可以确保我的代码能够接收ipInteger值吗?


2
obj是什么类型?它是如何创建和填充的? - JB Nizet
1
尝试使用Long.parseLong(int)而不是强制转换int值。 - Sherwin Obciana
1
@SherwinObciana:鉴于obj.get("ipInt")显然返回Integer,我无法看出这将如何工作。 - Jon Skeet
1
一些 JSON 库允许您强制将整数数字解析为 long,这将完全解决您的问题。这里是 jackson 的解决方案(如果您正在使用它)。 - ernest_k
6个回答

56

IntegerLong 都是 Number 的子类,因此我认为您可以使用:


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

无论 obj.get("ipInt") 返回的值是一个 Integer 引用还是一个 Long 引用,这都应该可以正常工作。它的缺点是如果在 JSON 中将 ipInt 指定为浮点数(例如 "ipInt": 1.5),它也会 默默地 继续执行,而你可能希望抛出异常。

可以 使用 instanceof 来检查具体的 LongInteger,但这样做会很丑陋。


1
我发现它更具弹性,特别是在处理“格式不正确”的 1.51. 时,如果我们假设 ipInt 应该是一个整数。它将会“默默地成功”而不是“显式崩溃”。 - Matthieu
2
@Matthieu:你的意思是说你更喜欢一种情况,即无效数据被静默地传递到系统中,导致数据丢失?我个人更喜欢尽早捕获无效数据并产生硬错误。如果某些代码试图使用非数字更新我的银行余额,我宁愿让系统崩溃而不是将其设置为0 :) - Jon Skeet
1
亲爱的上帝,我明白你的意思 ;) 我想这主要取决于情况:当你处理金钱时,硬崩溃显然是首选。但我有一些进程应该(几乎)永远不会停止,因此必须继续使用最后正确的配置。当然,在这种情况下,我们应该捕获异常并至少记录它。 好的,当我写这个的时候,我被说服了。谢谢 :) - Matthieu

8
我们不知道obj.get()返回什么,所以很难说确切的情况,但当我使用返回Number子类的方法时,我发现将其强制转换为Number并调用相应的xxxValue()比让自动解包抛出ClassCastException更安全:
long ipInt = ((Number)obj.get("ipInt")).longValue();

这样做,您就可以将代码中的显示拆箱转换为long类型,并能够处理包含.的数据,该操作会返回FloatDouble类型。


我标记了日期:写了与Jon Skeet几乎完全相同的答案,但声望只有他的1/1000左右 ;) - Matthieu

3
Long.valueOf(jo.get("ipInt").toString());

可以了。


2
在 Kotlin 中,我只需使用以下内容:
val myInt: Int = 10
val myLong = myInt.toLong()

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);
}

请解释代码的作用以及为什么它能回答这个问题。 - Matthieu
有些情况下这个有效。谢谢! - Saptak P

0
你提到当前的方法在提供整数范围外的值时有效,但在整数范围内失败。这对于一个 API 来说是一种奇怪的行为,因为它似乎需要你自己检查返回类型。你可以这样做。通常的方式是使用 "instanceof"。类似这样的代码:
long ipInt;
Object o = obj.get("ipInt");
if (o instanceof Integer) {
    ipInt = ((Integer) o).intValue();
} else if (o instanceof Long) {
    ipInt = ((Long) o).longValue();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接