该问题所涉及的程序是整除两个long型的数值。被除数表示一天里的微秒数,而除数表示一天里的毫秒数。这个程序会打印什么呢?
public class LongDivision {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}
}
如果一切正常的话,似乎应该打印的结果是1000,然而
打印的结果确实5,到底发生了什么?
问题在于常数MICROS_PER_DAY的计算确实溢出了。虽然计算的结果适合放入long中,但是这个结果确不适合放入int中。这个计算完全是以int类型来执行的,并且只有在计算完成之后,其结果才会被提升为long型。而此时已经太迟,计算已经溢出。
那么为什么常数MICROS_PER_DAY的计算会以int来执行的呢?因为所有连乘的因子都是int型数值。当两个int数值相乘时,得到的还是int。java不具有目标确定类型的特性。
程序改正如下
public class LongDivision {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}
}