在Java中验证从 long
到 int
的强制转换不丢失任何信息的最惯用的方法是什么?
这是我目前的实施:
public static int safeLongToInt(long l) {
int i = (int)l;
if ((long)i != l) {
throw new IllegalArgumentException(l + " cannot be cast to int without changing its value.");
}
return i;
}
10 回答
但龙不能超过最大:)
我想我会这样做:
我认为这比重复铸造更清楚地表达了意图......但它有点主观 .
注意潜在的兴趣 - 在C#中它只是:
使用BigDecimal:
Java整数类型表示为signed . 输入介于231和232(或-231和-232)之间时,演员会成功但你的测试会失败 .
要检查的是
long
的所有高位是否都相同:使用 Java 8 添加了一个新方法来做到这一点 .
如果溢出,将抛出
ArithmeticException
.见:Math.toIntExact(long)
Java 8中添加了其他几种溢出安全方法 . 它们以精确结尾 .
例子:
Math.incrementExact(long)
Math.subtractExact(long, long)
Math.decrementExact(long)
Math.negateExact(long),
Math.subtractExact(int, int)
我声称,看看是否更改值的显而易见的方法是强制转换并检查结果 . 但是,我会在比较时删除不必要的演员表 . 我也不太热衷于一个字母变量名称(异常
x
和y
,但不是当它们意味着行和列(有时分别)) .但是,如果可能的话,我真的想避免这种转换 . 显然,有时候这是不可能的,但在这些情况下,就客户端代码而言,
IllegalArgumentException
几乎肯定是错误的例外 .DONT: This is not a solution!
我的第一个方法是:
但这仅仅是将long转换为int,可能会创建新的
Long
实例或从Long池中检索它们 .缺点
如果数字不在
Long
的池范围内,则Long.valueOf
会创建一个新的Long
实例[-128,127] .intValue
实现只做以下事情:所以这可以被认为比仅仅将
long
转换为int
更糟糕 .另一个解决方案可以是:
我已经尝试过这种情况,因为客户端正在执行POST,而服务器数据库只能理解整数,而客户端只有Long .
使用Google Guava的Ints类,您的方法可以更改为:
来自链接的文档:
顺便说一句,你不需要
safeLongToInt
包装器,除非你想在不进行大量重构的情况下更改功能 .这是一个解决方案,万一你不关心 Value ,以防它需要更大;)