You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java新手问询:short与long变量溢出差异及强制转换必要性

为什么long和short在溢出场景下表现不同?

嘿,这个问题的核心其实是Java整数运算的自动类型提升和溢出行为在不同类型下的差异,我给你拆解得明明白白:

先搞懂Java整数运算的基础规则

咱们先达成一个共识:当你对byte、short、int这些整数类型做运算时,JVM会自动把它们提升为int类型来执行计算——除非你显式地把某个操作数强制转换为更大的类型(比如long),否则所有中间计算步骤都会被限制在int的范围内。一旦计算结果超过int的取值上限(2^31-1,也就是2147483647)或者低于下限(-2^31,也就是-2147483648),就会发生溢出,结果会变成一个看似无意义的负数(因为整数在Java里是补码存储的)。


关于long类型的两个例子差异

先看你给出的long计算代码:

第一个正确的例子:

long myLong = (long)(50_000 + 10 * (long)(myByte + myShort + myInt));

这里的关键是内层的(long)强制转换:

  1. myByte + myShort + myInt被强制转换成了long类型,所以这个求和结果是一个long值(2000155100,远小于long的最大值);
  2. 接下来10 * 这个long值的计算也会在long范围内进行,结果是20001551000;
  3. 加上50000之后还是long类型,最后外层的(long)转换其实是多余的,但不影响结果;
  4. 整个过程没有溢出,所以最终得到正确的结果20001601000。

第二个溢出的例子:

long myLong2 =(long)(50_000 + 10 * (myByte + myShort + myInt));

这里没有给内层求和加(long)转换,问题就出在这里:

  1. myByte + myShort + myInt被自动提升为int计算,结果是2000155100(这个数刚好没超过int的上限,暂时没问题);
  2. 但接下来10 * 这个int值的计算还是在int范围内进行,2000155100*10=20001551000——这个数远远超过了int的最大值2147483647,直接发生溢出,变成了负数-1473235480;
  3. 然后加上50000,还是基于溢出后的int值计算,结果依然是负数;
  4. 最后外层的(long)转换只是把这个负数转成了long类型,所以结果就是你看到的-1473235480。

简单说:第一个例子把内层计算提前升到long,避免了溢出;第二个例子全程用int计算,中间步骤溢出了,最后转long也救不回来。


关于short类型的两个例子结果相同

再看short的计算代码:

两个例子的代码:

short myShortTest = (short)(50_000 + 10*(short)(myByte + myInt +myShort));
short myShortTest2 = (short)(50_000 + 10*(myByte + myInt +myShort));

为什么这两个结果都是13800?咱们拆开看:

  1. 第二个例子(无内层转换):

    • myByte + myInt + myShort自动提升为int计算,结果是2000155100;
    • 乘以10得到20001551000(int溢出,但没关系,因为最后要转short);
    • 加上50000得到20001601000;
    • 最后转short时,Java会取这个数的低16位(因为short是16位类型),计算后得到13800。
  2. 第一个例子(有内层(short)转换):

    • myByte + myInt + myShort先转成short——但这个求和结果2000155100远大于short的最大值32767,所以转short时已经溢出,得到的是这个数的低16位(也就是-3620);
    • 然后10*-3620=-36200,加上50000得到13800;
    • 最后转short还是13800。

简单说:不管中间有没有转short,最后一步都是把最终结果的低16位取出来当short值,刚好两次计算的最终结果低16位都是13800,所以输出相同。


总结一下:

  • long的差异是因为中间计算是否在大类型中进行,溢出发生在int阶段就会导致错误结果;
  • short的结果相同是因为最终都会取低16位,中间的溢出不影响最终的截断结果。

内容的提问来源于stack exchange,提问作者itay k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:19:08