代码改变世界

[hyddd的FindBugs分析记录]M D ICAST] Result of integer multiplication cast to long

2009-04-01 21:10  hyddd  阅读(4005)  评论(0编辑  收藏  举报

[M D ICAST] Result of integer multiplication cast to long [ICAST_INTEGER_MULTIPLY_CAST_TO_LONG]

This code performs integer multiply and then converts the result to a long, as in:

 
long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }

If the multiplication is done using long arithmetic, you can avoid the possibility that the result will overflow. For example, you could fix the above code to:

	long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; } 

or

	static final long MILLISECONDS_PER_DAY = 24L*3600*1000;
long convertDaysToMilliseconds(int days) { return days * MILLISECONDS_PER_DAY; }

 

其实看上面的例子可以看到了

long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }  

这段代码是有可能溢出的,建议把代码改为下面:

long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; } 

 

用过VB6的人应该了解为什么会这样,因为在VB6里面一不小心就有可能出现这种溢出,在这里,JAVA认为:int * int * .....它的结果还是一个int!为什么编译器不能自动识别呢?答案是:很麻烦,并且这会使用编译器的效率非常低!对于有汇编经验的人来说,应该了解用汇编实现动态判断一个结果应该分配到一个long的空间还是int的空间有多复杂吧,而编译器有不能随便随便把int * int 的结果分配一个long空间,因为这会非常浪费内存,所以出于对效率和资源的考虑,最后的决定就是,凡是int * int * ....这样的计算结果一律都存放到int空间里,如果是long * int * .....则一律存放到long空间里,这就解释了为什么上面要在1000后面加个"L"了。:>