Java Puzzles
昨天开始看Java Puzzle这本书,这是一本讲述Java及JDK中让人迷惑的地方的一本书。书中所讲的东西确实很让人迷惑,我在看的过程中不断冒冷汗。
为了加深记忆,每天做一次笔记,记录其中的Puzzles。
Puzzle 1
public static boolean isOdd(int i){
return i % 2 == 1;
}
这个Puzzle的关键在于,%操作符在对负数操作时返回的不是 1,而是 -1。 Java中对于%的定义是:(a/b)*b +(a%b) = a
因此正确的判断奇数的方法应该是:i%2 != 0 。
Puzzle 2
System.out.println(2.00-1.10)
这条语句打印出来的是什么?
这个Puzzle的是Double.toString()方法不一定会产生准确的精度,所有的浮点数在计数时都会存在偏差,应该尽量使用BigDecimal来进行运算。
Puzzle 3
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000 ;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
上面这段代码会打印出什么?
看到这个Puzzle的答案时,我直冒冷汗,暗自祈祷以前写过的代码没出现这样的问题。上面这段代码会导致Overflow,这个Overflow是在计算MICROS_PER_DAY时产生的。
虽然MICROS_PER_DAY声明是long型,但是计算(24 * 60 * 60 * 1000 * 1000)这个表达式时,仍然是以int型运算,并不会转型为long再计算,因此导致Overflow。
因此保险的写法是:
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000 ;
这个Puzzle严重违背了Unix的补救原则:出现异常时,马上退出并给出足够错误信息。
看过这几个Puzzle之后,让我对这本书产生了非常浓厚的兴趣。Java API和JDK原来存在着如此多不为人知的秘密,让人捉摸不定。
从一个语言及平台来讲,存在着这种需要使用者时时注意的陷阱是非常不友好的。这些所谓的“奇技淫巧”对于使用者来说是一种恶梦。
在Java Puzzle这本书中,作者也提到了当初在设计API及JDK时,应该改进的方法,可惜的是,这些暂时是无法实现了。
昨天开始看Java Puzzle这本书,这是一本讲述Java及JDK中让人迷惑的地方的一本书。书中所讲的东西确实很让人迷惑,我在看的过程中不断冒冷汗。
为了加深记忆,每天做一次笔记,记录其中的Puzzles及自己在看书过程中的一些想法。
Puzzle 1
public static boolean isOdd(int i){
return i % 2 == 1;
}
这个Puzzle的关键在于,%操作符在对负数操作时返回的不是 1,而是 -1。 Java中对于%的定义是:(a/b)*b +(a%b) = a
因此正确的判断奇数的方法应该是:i%2 != 0 。
Puzzle 2
System.out.println(2.00-1.10)
这条语句打印出来的是什么?这个Puzzle的是Double.toString()方法不一定会产生准确的精度,所有的浮点数在计数时都会存在偏差,应该尽量使用BigDecimal来进行运算。
Puzzle 3
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000 ;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
上面这段代码会打印出什么?
看到这个Puzzle的答案时,我直冒冷汗,暗自祈祷以前写过的代码没出现这样的问题。上面这段代码会导致Overflow,这个Overflow是在计算MICROS_PER_DAY时产生的。虽然MICROS_PER_DAY声明是long型,但是计算(24 * 60 * 60 * 1000 * 1000)这个表达式时,仍然是以int型运算,并不会转型为long再计算,因此导致Overflow。
因此保险的写法是:
final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 L* 60 * 60 * 1000 ;
这样子在计算过程中就会装所以的数字转换成long型,避免了Overflow的错误。其实这个Puzzle严重违背了Unix的补救原则:出现异常时,马上退出并给出足够错误信息。
看过这几个Puzzle之后,让我对这本书产生了非常浓厚的兴趣。Java API和JDK原来存在着如此多不为人知的秘密,让人捉摸不定。从一个语言及平台来讲,存在着这种需要使用者时时注意的陷阱是非常不友好的。这些所谓的“奇技淫巧”对于使用者来说是一种恶梦。在Java Puzzle这本书中,作者也提到了当初在设计API及JDK时,应该改进的方法,可惜的是,这些暂时是无法实现了。