我的日常

登录/注册
您现在的位置:论坛 资料库 JAVA开发 > Integer类型比较的问题
总共48087条微博

动态微博

查看: 1780|回复: 3

Integer类型比较的问题

[复制链接]
admin    

1244

主题

544

听众

1万

金钱

管理员

  • TA的每日心情

    2021-2-2 11:21
  • 签到天数: 36 天

    [LV.5]常住居民I

    管理员

    跳转到指定楼层
    楼主
    发表于 2016-11-09 16:44:42 |只看该作者 |倒序浏览
    工作几年了,居然还是出现这个问题,最近做websocket通信,其中在SystemWebSocketHandler类中的一个代码片段,判断条件如下:
    1. /**
    2.      * 给当前组发消息
    3.      * @Author    张志朋
    4.      * @param session
    5.      * @param message  void
    6.      * @Date    2016年8月9日
    7.      * 更新日志
    8.      * 2016年8月9日 张志朋  首次创建
    9.      *
    10.      */
    11.     @SuppressWarnings("rawtypes")
    12.     public void sendMessageToGroup(WebSocketSession session,TextMessage message) {
    13.         try {
    14.             User currentUser = (User)      session.getAttributes().get(Constants.CURRENT_USER);
    15.             Integer groupId= currentUser.getGroupId();
    16.             Iterator iter = users.entrySet().iterator();
    17.             while (iter.hasNext()) {
    18.                 Map.Entry entry = (Map.Entry) iter.next();
    19.                 WebSocketSession webSocket = (WebSocketSession) entry.getKey();
    20.                 User user = (User) entry.getValue();
    21.                 Integer uGroupId= user.getGroupId();
    22.                 if(groupId==uGroupId&&!currentUser.getId()==user.getId()){
    23.                     if(webSocket.isOpen()){
    24.                         try {
    25.                             webSocket.sendMessage(message);
    26.                         } catch (IOException e) {
    27.                             e.printStackTrace();
    28.                         }
    29.                     }
    30.                 }
    31.               }
    32.         } catch (Exception e) {
    33.             e.printStackTrace();
    34.         }
    35.     }
    复制代码

    目的是如果用户在同一个组并且不是本人然后发送消息,说白了就是群发消息。
    但是看判断类型Integer并且用了==。
    首先给大家看一段代码:
    1. package com.test;
    2. /**
    3. *
    4. * @author ZZP
    5. *
    6. */
    7. public class TestInteger {
    8.     /**
    9.      * @param args
    10.      */
    11.     public static void main(String[] args) {
    12.         int i = 128;
    13.         Integer i2 = 128;
    14.         Integer i3 = new Integer(128);
    15.         //Integer会自动拆箱为int,所以为true
    16.         System.out.println(i == i2);
    17.         System.out.println(i == i3);
    18.         System.out.println("**************");
    19.         Integer i5 = 127;//java在编译的时候,被翻译成-> Integer i5 = Integer.valueOf(127);
    20.         Integer i6 = 127;
    21.         System.out.println(i5 == i6);//true
    22.         /*Integer i5 = 128;
    23.         Integer i6 = 128;
    24.         System.out.println(i5 == i6);//false
    25. */        Integer ii5 = new Integer(127);
    26.         System.out.println(i5 == ii5); //false
    27.         Integer i7 = new Integer(128);
    28.         Integer i8 = new Integer(123);
    29.         System.out.println(i7 == i8);  //false
    30.     }
    31. }
    复制代码

    首先,17行和18行输出结果都为true,因为Integer和int比都会自动拆箱(jdk1.5以上)。
    22行的结果为true,而25行则为false,很多人都不动为什么。其实java在编译Integer i5 = 127的时候,被翻译成-> Integer i5 = Integer.valueOf(127);所以关键就是看valueOf()函数了。只要看看valueOf()函数的源码就会明白了。JDK源码的valueOf函数式这样的:
    1. public static Integer valueOf(int i) {
    2. 2         assert IntegerCache.high >= 127;
    3. 3         if (i >= IntegerCache.low && i <= IntegerCache.high)
    4. 4             return IntegerCache.cache[i + (-IntegerCache.low)];
    5. 5         return new Integer(i);
    6. 6     }
    复制代码

    看一下源码大家都会明白,对于-128到127之间的数,会进行缓存,Integer i5 = 127时,会将127进行缓存,下次再写Integer i6 = 127时,就会直接从缓存中取,就不会new了。所以22行的结果为true,而25行为false。
    对于27行和30行,因为对象不一样,所以为false。
    我对于以上的情况总结如下:
    ①无论如何,Integer与new Integer不会相等。不会经历拆箱过程,i3的引用指向堆,而i4指向专门存放他的内存(常量池),他们的内存地址不一样,所以为false
    ②两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false
    java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存
    ③两个都是new出来的,都为false
    ④int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比


    科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、科帮网管理员和版主有权不事先通知发贴者而删除本文


    JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

    1

    主题

    0

    听众

    117

    金钱

    三袋弟子

    该用户从未签到

    沙发
    发表于 2016-11-18 16:34:04 |只看该作者
    果然是高手!受教了,这个论坛交流学习很不错
    回复

    使用道具 举报

    33

    主题

    1

    听众

    409

    金钱

    四袋长老

    该用户从未签到

    板凳
    发表于 2016-12-08 10:56:35 |只看该作者
    学习了,果然是明白人
    回复

    使用道具 举报

    5

    主题

    0

    听众

    316

    金钱

    四袋长老

    该用户从未签到

    地板
    发表于 2017-08-11 19:33:22 |只看该作者

    谢谢楼主的分享!。。。
    回复

    使用道具 举报

    快速回复
    您需要登录后才可以回帖 登录 | 立即注册

       

    关闭

    站长推荐上一条 /1 下一条

    发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
    快速回复 返回顶部 返回列表