《Java解惑》书摘
例子1:关于char数组的输出
System.out.println("H" + "a");//输出:Ha
System.out.println('H' + 'a');//输出:169
System.out.println("" + 'H' + 'a');//输出:Ha
System.out.println("//////////////////");
System.out.println("2 + 2 = " + 2 + 2);//输出:2 + 2 = 22
System.out.println("2 + 2 = " + (2 + 2));//输出:2 + 2 = 4
System.out.println("//////////////////");
char[] char1 = {'1', '2', '3'};
Object char2 = new char[] {'1', '2', '3'};
System.out.println(char1);//输出:123
System.out.println(char2);//输出:[C@55e83f9
System.out.println("test-" + char1);//输出:test-[C@55e83f9
System.out.println("test-" + char1.toString());//输出:test-[C@55e83f9
System.out.println("test-" + String.valueOf(char1));//输出:test-123
System.out.println("//////////////////");
例子2:
Random random = new Random();
StringBuffer sBuffer = null;
switch(random.nextInt(2)) {
case 1:sBuffer = new StringBuffer('A');
case 2:sBuffer = new StringBuffer('B');
default:sBuffer = new StringBuffer('C');
}
sBuffer.append('a');
sBuffer.append('b');
sBuffer.append('c');
System.out.println(sBuffer);//输出:abc
}
这段程序有三个BUG:
- Random.nextInt(int n)方法的使用错误:
先看下这个方法的API:
public int nextInt(int n)
返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
所以,此处应改为:switch(random.nextInt(3)) { - case子句中没有break语句:
导致前面的赋值被后面的赋值覆盖。 - StringBuffer类的构造方法使用错误:
StringBuffer不支持传入参数为字符(char)的构造方法,应改为传入字符串(String),
所以,应改为:sBuffer = new StringBuffer("A");
例子3:会死循环的代码
//死循环1
int start1 = Integer.MAX_VALUE-1;
for(int start7=start1; start7<=start1+1; start7++) {
System.out.println("loop..");
}
//死循环2
double start2 = 1.0 / 0.0;
double start3 = Double.POSITIVE_INFINITY;//与上句等价,可替代
while(start2 == (start2+1)) {
System.out.println("loop..");
}
//死循环3
double start4 = 0.0 / 0.0;
double start5 = Double.NaN;//与上句等价,可替代
while(start4 != start4) {
System.out.println("loop..");
}
//死循环4
String start6 = "test";
while(start6 != (start6+0)) {
System.out.println("loop..");
}
//死循环5
byte start7 = -1;//死循环
// short start7 = -1;//死循环
// int start7 = -1;//循环32次
// long start7 = -1;//循环64次
int count = 0;//循环次数
while(start7 != 0) {
start7 >>>= 1;
System.out.println("loop..");
count++;
}
System.out.println("循环次数 = " + count);
//死循环6
int start8 = Integer.MIN_VALUE;
// Long start8 = Long.MIN_VALUE;
while(start8 != 0 && start8 == -start8) {
System.out.println("loop..");
}
补充说明:
- 关于Infinity和NaN(死循环2和3)
double d = 1.0 / 0; System.out.println(d); //输出:Infinity System.out.println(d + 1); //输出:Infinity System.out.println(d == d + 1); //输出:true d = 0.0 / 0; System.out.println(d); //输出:NaN System.out.println(d + 1); //输出:NaN System.out.println(d == d + 1); //输出:false System.out.println(Double.NaN == Double.NaN);//输出:false Double a = new Double(Double.NaN); Double b = new Double(Double.NaN); System.out.println(a.equals(b));//输出:true
- 关于Java的自动窄化原生类型转换(死循环5)
分析 short start7 = -1; 和 start7 >>>= 1;这两句代码:
在执行移位操作时,第一步是将start7提升为start7nt类型,因为所有的算术操作都会对short,byte,char类型的操作数执行这样的提升;
这种提升是拓宽了原生类型,没有信息的损失,执行的是符号扩展,start7的值提升后是0xffffffff,start7>>>1之后得到的是0x7fffffff;
将这个值再存入start7中的时候,为了将int数值存入short变量,Java自动执行了可怕的窄化原生类型,直接把高16位截掉,剩下(short)0xffff,又回到了起点,从而导致了死循环。
这提醒了我们,不要在short,byte,char类型上使用复合赋值操作符,很容易出问题,而且这种隐性的窄化类型转换,在丢失信息的同时,结果也可能是灾难性的。 - 关于Java中的特殊值(死循环6)
Java使用2的补码的算术运算是不对称的。
对于每一种有符号的整数类型(byte、short、int和long),负的数值总是比正的数值多一个,这个多出来的数值总是这个类型所能表示的最小值;
对Integer.MIN_VALUE取负值并不会改变它的值,对这个值取负值将会产生溢出,但是Java自动忽略了这种溢出;同理对Long.MIN_VALUE等也是如此。
《Java解惑》书摘的更多相关文章
- Code Simplicity–The Science of Software Development 书摘
Chapter1 Introduction That is the art and talent involved in programming—reducing complexity to simp ...
- 《CODE》书摘
2016-11-08 14:59:16 可以说英语词汇就是一种编码. 2016-11-08 15:19:04 实际上任何两种不同的东西经过一定的组合都可以代表任何种类的信息. 2016-11-08 1 ...
- 《C Elements of Style》 书摘
<C Elements of Style> 书摘 学完C语言和数据结构后,虽然能解决一些问题,但总觉得自己写的程序丑陋,不专业.这时候看到了Steve Oualline写的<C El ...
- Visual Studio Code 代理设置
Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代码编辑器(包括 IDE),例如 Fron ...
- 我们是怎么做Code Review的
前几天看了<Code Review 程序员的寄望与哀伤>,想到我们团队开展Code Review也有2年了,结果还算比较满意,有些经验应该可以和大家一起分享.探讨.我们为什么要推行Code ...
- Code Review 程序员的寄望与哀伤
一个程序员,他写完了代码,在测试环境通过了测试,然后他把它发布到了线上生产环境,但很快就发现在生产环境上出了问题,有潜在的 bug. 事后分析,是生产环境的一些微妙差异,使得这种 bug 场景在线下测 ...
- 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM
刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...
- 在Visual Studio Code中配置GO开发环境
一.GO语言安装 详情查看:GO语言下载.安装.配置 二.GoLang插件介绍 对于Visual Studio Code开发工具,有一款优秀的GoLang插件,它的主页为:https://github ...
- 代码的坏味道(14)——重复代码(Duplicate Code)
坏味道--重复代码(Duplicate Code) 重复代码堪称为代码坏味道之首.消除重复代码总是有利无害的. 特征 两个代码片段看上去几乎一样. 问题原因 重复代码通常发生在多个程序员同时在同一程序 ...
- http status code
属于转载 http status code:200:成功,服务器已成功处理了请求,通常这表示服务器提供了请求的网页 404:未找到,服务器未找到 201-206都表示服务器成功处理了请求的状态代码,说 ...
随机推荐
- LRU Cache 解答
Question Design and implement a data structure for Least Recently Used (LRU) cache. It should suppor ...
- UVA 10047-The Monocycle(队列bfs+保存4种状态)
题意:给你一张地图,S代表起点,T代表终点,有一个轮盘,轮盘平均分成5份,每往前走一格恰好转1/5,轮盘只能往前进,但可以向左右转90°,每走一步或是向左向右转90° 要花费1单位的时间,问最少的时间 ...
- hdu2208之搜索
唉,可爱的小朋友 Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- python语言磁力搜索引擎源码公开,基于DHT协议
原文地址: http://www.cnblogs.com/huangxie/p/5550680.html
- python中使用mahotas包实现高斯模糊
高斯模糊 import mahotas as mh import numpy as np from matplotlib import pyplot as plt image=mh.imread('i ...
- Android应用程序组件Content Provider的启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6963418 通过前面的学习,我们知道在Andr ...
- 监控代码运行时长 -- StopWatch用法例程
在.net环境下,精确的测量出某段代码运行的时长,在网络通信.串口通信以及异步操作中很有意义.现在做了简单的总结.具体代码如下: (1).首先 using System.Diagnostics; (2 ...
- 网页 php开发中html空文本节点问题user agent stylesheetbody
最近开发中遇到一个奇怪的问题,我的一个网站头部,代码固定不变,放在了不同的模板进行展示,一部分出现了问题,总是距离相差8个像素,用firebug查看发现:meta 跑到 body 下面去了,并且发现了 ...
- latex 固定图片位置
1,插入并列的子图 \usepackage{subfigure} \begin{figure}[H] \centering \subfigure[SubfigureCaption]{ \label{F ...
- 全分布式环境下,DataNode不启动的问题解决
问题出现:机器重启之后,再次在master结点上面执行start-all.sh,发现有一个datanode没有启动,通过jps检查之后,发现slave1上面的datanode进程未启动 原因:每次na ...