谜题22:URL的愚弄
public class Main22 {
public static void main(String[] args) {
System.out.print("iexplore:");
http://www.google.com;
System.out.println(":maximize");
}
}
执行结果:iexplore::maximize
因为http:被当做语句标号
谜题23:不劳而获
import java.util.Random;
public class Main23 {
private static Random rnd = new Random();
public static void main(String[] args) {
StringBuffer word = null;
switch(rnd.nextInt(2)){
case 1:word = new StringBuffer('P');
case 2:word = new StringBuffer('G');
default:word = new StringBuffer('M');
}
word.append('a');
word.append('i');
word.append('n');
System.out.println(word);
}
}
上面的程序目的是等概率的打印 Pain、Gain、Main 三个单词,但多次运行程序却发现永远只会打印 ain,这是为什么?
第一个问题在于:
rnd.nextInt(2)只会返回0、1 两个数字,所以上面只会走case 1: 的分支语句,case 2: 按理是永远不会走的。
第二个问题在于:如果case语句不以break结束时,则一直会往向运行,即直到执行到break的case语句止,所以上面的的语句每次都会执行default分支语句。
第三个问题在于:StringBuffer的构造函数有两种可接受参数的,
一个是StringBuffer(int capacity)、另一个是StringBuffer(String str),上面用的是StringBuffer(char)构造函数,实质上运行时将字符型转换成了int型,这样将字符当作StringBuffer的初始容量了,而不是字符本身。
不管什么时候,都要尽可能使用熟悉的惯用法和API,如果必须使用不熟悉的API,请仔细阅读其文档。
谜题24:尽情享受每一个字节
下面的程序循环遍历byte数值,以查找某个特定值,这个程序会打印什么呢?
public class Main24 {
public static void main(String[] args) {
for(byte b = Byte.MIN_VALUE;b<Byte.MAX_VALUE;b++){
if(b==0x90){
System.out.print("Joy!");
}
}
}
}
运行程序,结果是不会打印出任何内容。
0x90是一个int型常量,超出了byte数值的范围。
((byte)0x90==0x90)结果为false。为了比较,java通过拓宽原生类型转换将byte提升为int,然后两个int比较。(byte)0x90转为int为-112,而0x90是144。
总之,要避免混合类型比较,因为它们内在地容易引起混乱。
谜题25:无情的增量操作
public class Main25 {
public static void main(String[] args) {
int j =0 ;
for(int i=0;i<10;i++){
j=j++;
}
System.out.println(j); //0
}
}
谜题26:在循环中
public class Main26 {
public static final int END =Integer.MAX_VALUE;
public static final int START = END-100;
public static void main(String[] args) {
int count =0;
for(int i = START;i<=END;i++){ //无限循环,当到达int最大值,继续加时,就回到int最小值了
count++;
}}}
所有的int变量都小于或等于Integer.MAX_VALUE的。并且再次执行增量操作时,会绕回到
Integer.MIN_VALUE.
int start = Integer.MAX_VALUE-1;
for(int i =start;i<=start+1;i++); //这是一个死循环
double i= Double.POSITIVE_INFINITY; //只要i足够大的浮点数即可
// double i = 1e56;
while(i==i+1){ //死循环
}
double j = 0.0/0.0; //Double.NaN,float也有NaN
System.out.println(j-j==0); //false ,只要一个操作数为NaN,结果就为NaN
while(j!=j){ //死循环
}
while(i!=i+0){}
给出i的定义,是上面是一个死循环,
可以使用Double,float中的NaN,也可以使用String类型,不要惊讶哦 如String i = "a"