`

Java中令人发狂的程序语言的特性

    博客分类:
  • Java
 
阅读更多

Java的Integer cache

Java代码   收藏代码
  1. Integer foo = 1000;  
  2. Integer bar = 1000;  
  3.   
  4. foo <= bar; // true  
  5. foo >= bar; // true  
  6. foo == bar; // false  
  7.   
  8. //然后,如果你的 foo 和 bar 的值在 127 和 -128 之间(包括)  
  9. //那么,其行为则改变了:  
  10.   
  11. Integer foo = 42;  
  12. Integer bar = 42;  
  13.   
  14. foo <= bar; // true  
  15. foo >= bar; // true  
  16. foo == bar; // true  

为什么会这样呢?你需要了解一下Java Interger Cache,下面是相关的程序,注意其中的注释

Java代码   收藏代码
  1. /** 
  2.  
  3.      * Returns a <tt>Integer</tt> instance representing the specified 
  4.  
  5.      * <tt>int</tt> value. 
  6.  
  7.      * If a new <tt>Integer</tt> instance is not required, this method 
  8.  
  9.      * should generally be used in preference to the constructor 
  10.      * <a href="mailto:{@link">{@link</a> #Integer(int)}, as this method is likely to yield 
  11.      * significantly better space and time performance by caching 
  12.      * frequently requested values. 
  13.      * 
  14.      * @param  i an <code>int</code> value. 
  15.      * @return a <tt>Integer</tt> instance representing <tt>i</tt>. 
  16.      * @since  1.5 
  17.      */  
  18.     public static Integer valueOf(int i) {  
  19.         if(i >= -128 && i <= IntegerCache.high)  
  20.             return IntegerCache.cache[i + 128];  
  21.         else  
  22.             return new Integer(i);  
  23.     }  

 

Java的异常返回

请看下面这段程序,你觉得其返回true还是false?

Java代码   收藏代码
  1. try {  
  2.     return true;  
  3. finally {  
  4.     return false;  
  5. }  

 在 javascript 和python下,其行为和Java的是一样的。

 

错误1:长整数赋值问题 

   系统有一个功能要产生邀请码,客户通过邀请码进行注册,但是邀请码要有过期时间,希望60天后过期,过期时间采用毫秒数: 

Java代码  收藏代码
  1. 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代码  收藏代码
  1. long EXPIRED_DATE = 60 * 24 * 60 * 60 * 1000L;  



错误2:数值越界的问题 
   
    我写的一个模块允许开发者注册插件,为了控制插件执行的先后顺序,因此我写了一个Orderable接口,插件实现该接口以决定执行的先后顺序(orderNo越小越先执行): 

Java代码  收藏代码
  1. public interface Orderable {  
  2.     /** 
  3.      * 排序号,越小越在前面 
  4.      */  
  5.     int getOrdreNo();  
  6. }  


    
    然后写了一个Comparator,以便可以通过java.util.Collections的 
   

Java代码  收藏代码
  1. sort(List<T> list,Comparator<? super T> c)  


    对插件List进行排序。Comparator是这样写的: 

Java代码  收藏代码
  1.    public class OrderableComparator implements Comparator {  
  2.     private static OrderableComparator intance = new OrderableComparator();  
  3.   
  4.     private OrderableComparator() {  
  5.     }  
  6.   
  7.     public int compare(Object obj1, Object obj2) {  
  8.         int order1 = Integer.MAX_VALUE;  
  9.         int order2 = Integer.MAX_VALUE;  
  10.         if (obj1 instanceof Orderable) {  
  11.             order1 = ((Orderable) obj1).getOrdreNo();  
  12.         }  
  13.         if (obj2 instanceof Orderable) {  
  14.             order2 = ((Orderable) obj2).getOrdreNo();  
  15.         }  
  16.         return order1 - order2;//① 大家注意这儿是出鬼的地方!!!  
  17.     }  
  18.   
  19.     public static OrderableComparator getIntance() {  
  20.         return intance;  
  21.     }  
  22. }  


    但是一个兄弟咆哮地告诉我,它的插件的getOrderNo()已经设置为Integer.MIN_VALUE,但是却在最后一位执行!!! 
    跟踪了代码,才发现是对数值越界问题的忽视而造成了这个低级错误,下面具体分析一下,如Plugin1的getOrdreNo()为Integer.MIN_VALUE,而Plugin2的getOrdreNo()为1,可是大家想想下面的计算值是多少呢? 
   

Java代码  收藏代码
  1. Integer.MIN_VALUE - 1  


   是2147483647!! 
   找到问题后改起来是不费工夫的: 

Java代码  收藏代码
  1. public int compare(Object obj1, Object obj2) {  
  2.     int order1 = Integer.MAX_VALUE;  
  3.     int order2 = Integer.MAX_VALUE;  
  4.     if (obj1 instanceof Orderable) {  
  5.         order1 = ((Orderable) obj1).getOrdreNo();  
  6.     }  
  7.     if (obj2 instanceof Orderable) {  
  8.         order2 = ((Orderable) obj2).getOrdreNo();  
  9.     }  
  10.        
  11.     if(order1 > order2){  
  12.         return 1;  
  13.     }else if(order1 < order2){  
  14.         return -1;  
  15.     }else{  
  16.         return 0;  
  17.     }  
  18. }  


分享到:
评论

相关推荐

    找乐儿-百度贴吧发狂 v1.0

    1. **BaiduTiebaFaKuang.exe**:这是主应用程序文件,通常是一个可执行程序,用户可以通过运行这个文件来启动"找乐儿-百度贴吧发狂 v1.0"软件。 2. **chinaz.com说明.txt**:这可能是一个来自知名网站Chinaz(站长...

    三子连珠游戏VC++程序

    编一棋盘游戏程序,可以选择人机对战和双人对战两种游戏模式,而人机模式下可以选择三种电脑等级,即简单的电脑、中等的电脑和令人发狂的电脑,电脑智能化程度随等级提高而提高。下棋双方分别以字符X和字符O为棋子。...

    27个经典趣味C++程序.rar

    本书收集的27个经典趣味C++程序展示了这门语言在不同领域中的应用,同时也为编程爱好者提供了一种学习和娱乐相结合的方式。以下是对这些程序内容的知识点分析。 首先,书中可能会包含一些基础的C++程序,例如...

    AS3 MD5姓名大战 源码

    ActionScript 3作为一款高级编程语言,具有面向对象的特性,能够高效地处理多媒体和网络通信。在本游戏中,AS3的灵活性和强大的控制能力得到了充分展现,尤其是在处理复杂的逻辑判断和动画效果上。 #### 四、总结 ...

    灵巧与指针回收灵巧与指针回收

    在编程语言中,资源管理尤其是内存管理是软件开发中一个非常重要的环节。在C++和Java这类语言中,程序员经常...与此同时,智能指针的深入理解也有助于在其他编程语言中,比如Java,对垃圾回收机制有更为透彻的认识。

    高中英语单词天天记self素材

    - “名词+self”:如“beauty's self”(美的化身)、“pity's self”(极令人遗憾的事物)等,这种用法赋予了“self”一种象征意义。 在搭配和句型中,“self”有多种使用方式,例如: - “动词+self”:如...

    方便快捷通讯录挺使用的一个东西

    标题中的“方便快捷通讯录”指的是这样一类应用,它能够帮助用户快速、高效地管理联系人信息,实现便捷的通信。这类应用通常具有多种功能,如分类管理、搜索查找、同步更新等,极大地提高了人们处理社交关系的效率。...

    C++分类习题大全.doc

    从提供的文件内容中,我们可以提取出以下关于C++编程语言的知识点: 1. 类和对象的基本概念:C++中的类是一种用户定义的数据类型,用于封装数据和操作数据的方法。对象是类的实例。 2. 构造函数的定义与使用:构造...

    关于快乐高兴的说说短语参考.doc

    “欢欣若狂”则更加夸张,形容人在极度的快乐中几乎像发狂一样。“心花怒放”则喻意心花盛开,把内心深处的喜悦比作花朵绽放,极具诗意。这些成语的使用,可以让我们的表达更加形象和生动,使听者或读者感同身受。 ...

    友元和运算符重载.pdf

    在C++编程语言中,友元和运算符重载是两个重要的特性,它们都与类的封装性有着密切的关系。 友元是C++中用于破坏封装性的一种机制。它允许外部函数或外部类访问一个类的私有(private)和保护(protected)成员。友元...

    鄂教版九年级下第11课《范进中举》同步练习精选.doc

    《范进中举》是清代小说家吴敬梓创作的讽刺杰作,收录于其著名的长篇讽刺小说《儒林外史》之中。本作品不仅是文学上的经典,同时也深刻地反映了封建社会的教育制度与社会风貌。在现代教育中,我们可以从《范进中举》...

    hibernate3.3 struts-2.3.20 spring3.2.3 整合框架

    SSH框架,全称为Struts2、Hibernate和Spring的集成,是Java Web开发中常见的三大开源框架的组合。这个整合框架提供了强大的模型-视图-控制器(MVC)架构支持,数据库操作以及依赖注入等特性,极大地提高了开发效率和...

    mybatis 逆向工程 generatorSqlmapCustom

    MyBatis逆向工程是开发过程中一个非常实用的特性,它可以帮助我们自动化生成与数据库表相关的Java接口、Mapper XML文件以及实体类,极大地提高了开发效率。`generatorSqlmapCustom`是MyBatis逆向工程的一个自定义...

    try except finally的用法.doc

    try-except-finally结构在C++中主要用于异常处理,能够增强程序对错误情况的响应和恢复能力。try块用于包含可能引发异常的代码,这包括诸如除以零、文件读写错误、网络断开等运行时错误。如果try块中的代码执行中...

    c++局部变量的作用范围

    在C++编程语言中,变量的作用范围是指变量在程序中可以被引用的区域。局部变量和全局变量是根据作用范围进行分类的两种不同类型的变量。局部变量的作用范围通常限于其所在函数内部,而全局变量的作用范围则覆盖整个...

    win10更改输入法切换方式(ctrl+空格)

    升级到win10后,很多更新还是特别喜欢的,但有一些更改有违以往的操作习惯,也到了让人发狂的地步,比如输入法切换,需要win+空格,特别不习惯,特别是对于it从业者更是如此,因为默认是中文输入法,大家都懂的 ...

    c,c++生存期,范围

    在C和C++编程语言中,变量的生存期(生命周期)是指变量在内存中存在的时间长度,而变量的作用范围(作用域)指的是变量在程序代码中的可见性和访问性。变量的存储类型定义了它们的存储方式和生存期。 变量主要有两...

    2017_2018学年中考英语一轮复习M开头词汇一讲义20180811126

    短语如"be/get/go mad" 意为“发狂,失去理智”,"drive sb mad" 表示某事使人极度烦躁,“Mum went mad when she heard the noise.”(妈妈听到噪音时很生气。) 3. **Magazine**:杂志,名词,指定期出版的印刷...

    C指针奥秘.txt C指针奥秘.txt

    C语言中的指针是编程语言的灵魂之一,它们为程序员提供了对内存地址的直接访问和操作能力。在本文件《C指针奥秘.txt》中,揭示了C语言指针的多种类型和用途,通过示例代码和详细解析,深入探讨了指针的内部工作机制...

    (中小学教育)中考语文复习:成语辨析专题课件.ppt

    例如,将原文中的词语替换为成语,可以使句子更具文学色彩,如“风和日丽”代替“天气不错”,“欣喜若狂”代替“高兴得快要发狂”,“早出晚归”描述父亲辛勤工作,“筋疲力尽”描绘疲劳状态,“人山人海”形容人群...

Global site tag (gtag.js) - Google Analytics