异常具有类型,这允许您查找类型并快速对问题进行分类。从文档中:
ArithmeticException:发生异常算术条件时抛出。例如,整数“除以零”将引发此类的实例。
此外,大多数异常都带有一条消息来构造,以帮助您进一步了解发生了什么。
try { int i = 0 / 0;} catch (ArithmeticException e) { e.printStackTrace();}打印:
java.lang.ArithmeticException: / by zero at [filename:line number]
但是,这是怎么发生的呢?
与许多其他编程语言一样,Java区分整数除法和浮点除法。
[JLS
15.17.2分区运营商/](http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.17.2)
二进制
/运算符执行除法,产生其操作数的商。左边的操作数是除数,右边的操作数是除数。整数除法取整为0。如果整数除数的除数的值为0,则ArithmeticException抛出。
如果您不熟悉整数除法,以下内容可能会让您感到惊讶:
System.out.println(1/2); // prints "0"
此处发生的是,由于被除数和除数都是
int,所以运算是整数除法,其结果四舍五入为
int。请记住,一个
int只能包含整数(范围有限,大约40亿个数字)。
您可以通过使至少一个操作数为浮点数来指定需要浮点除法。
System.out.println(1/2.0); // prints "0.5" System.out.println(1D/2); // prints "0.5"
D是数字文字的特殊后缀,以指定它是
double-precision值。还有
L的
long(64位整数)。
甲
double值需要被存储在一个
double变量中。
double v = 1D / 2; // v == 0.5 int i = 1D / 2; // DOESN'T COMPILE!!! Explicit cast needed!
请注意,执行哪种除法与最终将要使用的类型无关。它仅取决于被除数和除数的类型。
double v = 1 / 2; // v == 0.0 (!!!)
您还应该注意,
double也是有限的精度数字。
System.out.println(.2D + .7D - .9D); // prints "-1.1102230246251565E-16"
但是我的代码呢?
现在,让我们集中讨论代码所发生的事情:
timetaken = stopTime - startTime; timeInSecs = ((timetaken/1000)); speed = 45/timeInSecs;
很有可能发生的事情
timetaken被声明为
long。因此
timetaken/1000导致整数除法。如果
timetaken <1000是,则除法结果为
0。
此时,
timeInSecsa
double或a都无关紧要
float,因为已经执行了整数除法。这意味着
timeInSecs将根据其类型为
0或
0.0。
但是,从错误中您可以确定这
timeInSecs很可能是整数类型。否则,
45/timeInSecs将导致浮点除法而不是throw
导致
Infinity(特殊
double值)
ArithmeticException。
那么我们该如何解决呢?
我们可以通过声明变量来解决此问题,如下所示:
long timetaken;double timeInSecs;double speed;
然后按如下所示执行计算(请注意,
1000现在是一个
double值)。
timetaken = stopTime - startTime;timeInSecs = timetaken/1000D;speed = 45D/timeInSecs; // D is not necessary here, but it's good for clarity



