Java中令人发疯的程序语言的特性
Java中令人发狂的程序语言的特性Java的Integer cacheJava代码??Integer?foo??1000??Integer?bar??1000
Java中令人发狂的程序语言的特性
Java的Integer cacheJava代码??
- Integer?foo?=?1000;??
- Integer?bar?=?1000;??
- ??
- foo?<=?bar;?//?true??
- foo?>=?bar;?//?true??
- foo?==?bar;?//?false??
- ??
- //然后,如果你的?foo?和?bar?的值在?127?和?-128?之间(包括)??
- //那么,其行为则改变了:??
- ??
- Integer?foo?=?42;??
- Integer?bar?=?42;??
- ??
- foo?<=?bar;?//?true??
- foo?>=?bar;?//?true??
- foo?==?bar;?//?true??
为什么会这样呢?你需要了解一下Java Interger Cache,下面是相关的程序,注意其中的注释
Java代码??

- /**?
- ?
- ?????*?Returns?a?<tt>Integer</tt>?instance?representing?the?specified?
- ?
- ?????*?<tt>int</tt>?value.?
- ?
- ?????*?If?a?new?<tt>Integer</tt>?instance?is?not?required,?this?method?
- ?
- ?????*?should?generally?be?used?in?preference?to?the?constructor?
- ?????*?<a?href="mailto:{@link">{@link</a>?#Integer(int)},?as?this?method?is?likely?to?yield?
- ?????*?significantly?better?space?and?time?performance?by?caching?
- ?????*?frequently?requested?values.?
- ?????*?
- ?????*?@param??i?an?<code>int</code>?value.?
- ?????*?@return?a?<tt>Integer</tt>?instance?representing?<tt>i</tt>.?
- ?????*?@since??1.5?
- ?????*/??
- ????public?static?Integer?valueOf(int?i)?{??
- ????????if(i?>=?-128?&&?i?<=?IntegerCache.high)??
- ????????????return?IntegerCache.cache[i?+?128];??
- ????????else??
- ????????????return?new?Integer(i);??
- ????}??
?
Java的异常返回
请看下面这段程序,你觉得其返回true还是false?
Java代码??

- try?{??
- ????return?true;??
- }?finally?{??
- ????return?false;??
- }??
?在?javascript 和python下,其行为和Java的是一样的。
?
错误1:长整数赋值问题?
?? 系统有一个功能要产生邀请码,客户通过邀请码进行注册,但是邀请码要有过期时间,希望60天后过期,过期时间采用毫秒数:?
Java代码??

- long?EXPIRED_DATE?=?60?*?24?*?60?*?60?*?1000;??
?? 可是,测试人员告诉我,邀请码10天不到就过期了,我看了代码,百思不解,最后跟踪了代码,才发现
引用60 * 24 * 60 * 60 * 1000
并不会自动转化为long,而是一个int,10天的毫秒数就超过了int的最大值了,因此10天不到就过期了!?
?? 这儿犯下的错误是其实对 “整数字面值赋值时默认为int型”这个基础Java知识的忽视造成的.如果要让JVM将字面数字当成long,则必须在字面数字后显示加L标识,所以这个BUG是这样解决的:?
Java代码??

- long?EXPIRED_DATE?=?60?*?24?*?60?*?60?*?1000L;??
错误2:数值越界的问题?
???
??? 我写的一个模块允许开发者注册插件,为了控制插件执行的先后顺序,因此我写了一个Orderable接口,插件实现该接口以决定执行的先后顺序(orderNo越小越先执行):?
Java代码??

- public?interface?Orderable?{??
- ????/**?
- ?????*?排序号,越小越在前面?
- ?????*/??
- ????int?getOrdreNo();??
- }??
????
??? 然后写了一个Comparator,以便可以通过java.util.Collections的?
???
Java代码??

- sort(List<T>?list,Comparator<??super?T>?c)??
??? 对插件List进行排序。Comparator是这样写的:?
Java代码??

- ???public?class?OrderableComparator?implements?Comparator?{??
- ????private?static?OrderableComparator?intance?=?new?OrderableComparator();??
- ??
- ????private?OrderableComparator()?{??
- ????}??
- ??
- ????public?int?compare(Object?obj1,?Object?obj2)?{??
- ????????int?order1?=?Integer.MAX_VALUE;??
- ????????int?order2?=?Integer.MAX_VALUE;??
- ????????if?(obj1?instanceof?Orderable)?{??
- ????????????order1?=?((Orderable)?obj1).getOrdreNo();??
- ????????}??
- ????????if?(obj2?instanceof?Orderable)?{??
- ????????????order2?=?((Orderable)?obj2).getOrdreNo();??
- ????????}??
- ????????return?order1?-?order2;//①?大家注意这儿是出鬼的地方!!!??
- ????}??
- ??
- ????public?static?OrderableComparator?getIntance()?{??
- ????????return?intance;??
- ????}??
- }??
??? 但是一个兄弟咆哮地告诉我,它的插件的getOrderNo()已经设置为Integer.MIN_VALUE,但是却在最后一位执行!!!?
??? 跟踪了代码,才发现是对数值越界问题的忽视而造成了这个低级错误,下面具体分析一下,如Plugin1的getOrdreNo()为Integer.MIN_VALUE,而Plugin2的getOrdreNo()为1,可是大家想想下面的计算值是多少呢??
???
Java代码??

- Integer.MIN_VALUE?-?1??
?? 是2147483647!!?
?? 找到问题后改起来是不费工夫的:?
Java代码??

- public?int?compare(Object?obj1,?Object?obj2)?{??
- ????int?order1?=?Integer.MAX_VALUE;??
- ????int?order2?=?Integer.MAX_VALUE;??
- ????if?(obj1?instanceof?Orderable)?{??
- ????????order1?=?((Orderable)?obj1).getOrdreNo();??
- ????}??
- ????if?(obj2?instanceof?Orderable)?{??
- ????????order2?=?((Orderable)?obj2).getOrdreNo();??
- ????}??
- ???????
- ????if(order1?>?order2){??
- ????????return?1;??
- ????}else?if(order1?<?order2){??
- ????????return?-1;??
- ????}else{??
- ????????return?0;??
- ????}??
- }??