Java陷阱(三)
来源:互联网 发布:数据库安全技术有哪些 编辑:程序博客网 时间:2024/05/15 06:40
前言:摘自《Java解惑》。这些问题都很经典,可以细细品味。
问题:无情的增量
代码:
/** *无情的增量 * @authorLiangGzone */public class Increment { publicstatic void main(String[] args) { intj = 0; for(int i = 0; i < 100; i++) { j= j++; } System.out.println(j); }}分析:当++操作符被置于一个变量值之后时,其作用就是一个后缀增量操作符,表达式j++的值等于j在执行增量操作之前的初始值。因此,前面提到的赋值语句首先保存j的值,然后将j设置为其值加1,最后将j复位到它的初始值。换句话说,这个赋值操作等价于下面的语句序列:
int temp = j;
j = j + 1;
j = temp;
类似的问题:
public class Demo { publicstatic void main(String[] args) { intj = 0; j= j++; System.out.println(j); }}建议:不要在单个的表达式中对相同的变量赋值超过一次。
问题:变幻莫测的i值
代码:
/** *变幻莫测的i值 * @authorLiangGzone */public class Shifty { publicstatic void main(String[] args) { inti = 0; while(-1 << i != 0) i++; System.out.println(i); }}
分析:常量-1是所有32位都被置位的int数值(0xffffffff)。左移操作符将0移入到由移位所空出的右边的最低位,因此表达式(-1<< i)将i最右边的位设置为0,并保持其余的32 -i位为1。很明显,这个循环将完成32次迭代,因为-1<< i对任何小于32的i来说都不等于0。你可能期望终止条件测试在i等于32时返回false,从而使程序打印32,但是它打印的并不是32。实际上,它不会打印任何东西,而是进入了一个无限循环。问题在于(-1<< 32)等于-1而不是0,因为移位操作符之使用其右操作数的低5位作为移位长度。或者是低6位,如果其左操作数是一个long类数值。
建议:如果可能的话,移位长度应该是常量。
问题:什么样的声明能够让下面的循环变成一个无限循环?
While (i == i + 1) {}
代码:
/** *循环者 * @authorLiangGzone */public class LoopDemo { publicstatic void main(String[] args) { doublei = 1.0e40; while(i== i+1){ System.out.println("loop"); } }}分析:浮点数操作返回的是最接近其精确的数学结果的浮点数值。一旦毗邻的浮点数值之间的距离大于2,那么对其中的一个浮点数值加1将不会产生任何效果,因为其结果没有达到两个数值之间的一半。对于float类型,加1不会产生任何效果的最小级数是225,即33,554,432;而对于double类型,最小级数是254,大约是1.8 ×1016。
建议:用一个double或一个float数值来表示无穷大是可以的。将一个很小的浮点数加到一个很大的浮点数上时,将不会改变大的浮点数的值。
问题:什么样的声明能够让下面的循环变成一个无限循环?
While (i == i + 1) {}
代码:
/** *循环者2 * @authorLiangGzone */public class LoopDemo2 { publicstatic void main(String[] args) { doublei = Double.NaN; while(i!= i){ System.out.println("loop"); } }}分析:任何浮点操作,只要它的一个或多个操作数为NaN,那么其结果为NaN。一旦一个计算产生了NaN,它就被损坏了,没有任何更进一步的计算可以修复这样的损坏。NaN值意图使受损的计算继续执行下去,直到方便处理这种情况的地方为止。
建议:float和double类型都有一个特殊的NaN值,用来表示不是数字的数量。对于涉及NaN值的计算,其规则很简单也很明智,但是这些规则的结果可能是违背直觉的。
阅读链接:
Java陷阱(一)
Java陷阱(二)
Java陷阱(三)
Java陷阱(四)
Java陷阱(五)
Java陷阱(六)
- Java陷阱(三)
- 【JAVA陷阱与缺陷-->规则】(三)高级篇
- JAVA多线程编程陷阱总结三
- Java陷阱(二)
- Java陷阱(一)
- Java陷阱(四)
- Java陷阱(五)
- Java陷阱(六)
- C陷阱与缺陷(三)语义"陷阱"
- C陷阱与缺陷(三)--语义陷阱1
- C陷阱与缺陷(三)--语义陷阱2
- Flex数据绑定陷阱(三)
- C陷阱和指针基础(三)
- 读《C陷阱和缺陷》(三)
- Java 陷阱
- java陷阱
- 人生三大陷阱
- 人生三大陷阱
- myEclipse6.0 的jd_gui插件安装(myEclipse6.0直接查看jar文件的源码)
- 软件开发实践的24条军规
- Nginx+tomcat负载均衡session问题解决
- 【最权威】云计算的NIST定义
- POJ 1026 java语言
- Java陷阱(三)
- HDU 1263 水果 map容器
- 【黑马程序员】错误:“未安装全文搜索或无法加载某一全文组件”的解决方法
- cocos2d-x 自定义Touch事件处理类
- Android sdcard创建文件夹及写入工程目录视频资源
- iOS ASI http 框架详解
- 使用GruntJS搭建前端本地开发环境 (零)
- PHP扩展库开发
- iOS开发如何实现消息推送机制