第一次使用FindBugs插件,学习到关于valueOf的东西

前段时间在写一个发送报表邮件的功能时,写了几行很差的代码被带我的同事看到了。(生成报表的代码写的我很烦当时,时间也紧,一不小心就写出烂代码了。。。算了,就是自己比较菜,不为自己辩解了)
大概就是对象与常量比较时,没有把常量放在前面的错误,类似
User.getName().equals("Mike")
(上面这个代码当User的name成员变量为空时会报空指针异常)
对象与常量比较时,必须把常量放在前面,防止对象为空时报空指针异常。要写成类似
if(“name”.equals(obj))…
还有同样的错误如
if(List.size()>0&&List!=null) ...
(上面的代码应该先判断List!=null,否则可能有空指针异常。或者最好直接用工具包里的StringUtils.isNotBlank()判断)
这些问题很多新手都会不注意,是一个代码规范的问题。特别对于java这样讲究协作的工程语言,不规范代码引起的潜在问题很容易累积,然后导致奇怪的bug,让代码很难维护。所以写出符合规范,可维护的代码算Java程序员的基本素质吧。

后来同事给我推荐了一款插件叫FindBugs,说可以检查这样的问题。安装后发现真的好用!检查了一下刚写的代码,提示了下面这个问题:

Method invokes inefficient Number constructor; use static valueOf instead
Using new Integer(int) is guaranteed to always result in a new object whereas Integer.valueOf(int) allows caching of values to be done by the compiler, class library, or JVM. Using of cached values avoids object allocation and the code will be faster.
Values between -128 and 127 are guaranteed to have corresponding cached instances and using valueOf is approximately 3.5 times faster than using constructor. For values outside the constant range the performance of both styles is the same.
Unless the class must be compatible with JVMs predating Java 1.5, use either autoboxing or the valueOf() method when creating instances of Long, Integer, Short, Character, and Byte.

意思就是new Integer(int)这种用法是无效的数字构造,每次使用构造方法都会创建一个新的数字对象。而Integer.valueOf(int)会从缓存里取数字,避免每次都分配对象,速度更快,减少垃圾产生。尤其值在 -128 and 127时会每次用缓存,速度能快3.5倍。除非你的目的就是产生新的对象,否则最好用Integer.valueOf这种方式。

果然一用就有发现问题。那看一下Integer.valueOf()的源码:
(我用的是JDK1.7)

/**
    * Cache to support the object identity semantics of autoboxing for values between
    * -128 and 127 (inclusive) as required by JLS.
    *
    * The cache is initialized on first usage.  The size of the cache
    * may be controlled by the -XX:AutoBoxCacheMax=<size> option.
    * During VM initialization, java.lang.Integer.IntegerCache.high property
    * may be set and saved in the private system properties in the
    * sun.misc.VM class.
    */
   private static class IntegerCache {
       static final int low = -128;
       static final int high;
       static final Integer cache[];

       static {
           // high value may be configured by property
           int h = 127;
           String integerCacheHighPropValue =
               sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
           if (integerCacheHighPropValue != null) {
               int i = parseInt(integerCacheHighPropValue);
               i = Math.max(i, 127);
               // Maximum array size is Integer.MAX_VALUE
               h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
           }
           high = h;

           cache = new Integer[(high - low) + 1];
           int j = low;
           for(int k = 0; k < cache.length; k++)
               cache[k] = new Integer(j++);
       }

       private IntegerCache() {}
   }

   /**
    * Returns an {@code Integer} instance representing the specified
    * {@code int} value.  If a new {@code Integer} instance is not
    * required, this method should generally be used in preference to
    * the constructor {@link #Integer(int)}, as this method is likely
    * to yield significantly better space and time performance by
    * caching frequently requested values.
    *
    * This method will always cache values in the range -128 to 127,
    * inclusive, and may cache other values outside of this range.
    *
    * @param  i an {@code int} value.
    * @return an {@code Integer} instance representing {@code i}.
    * @since  1.5
    */
   public static Integer valueOf(int i) {
       assert IntegerCache.high >= 127;
       if (i >= IntegerCache.low && i <= IntegerCache.high)
           return IntegerCache.cache[i + (-IntegerCache.low)];
       return new Integer(i);
   }

果然如FindBugs中的描述一样,i在-128 到127时(high至少为127,至多是Integer最大值,默认配置127),直接从缓存数组里取。类加载时JVM就会执行IntegerCache 静态类里面的静态代码块,提前把Integer对象都创建好放到cache数组里了,用时候直接取。有意思哈~内部缓存。

所以有关于自动装箱的面试题

publicstaticvoidmain(String[] args) {          
       Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;   
       System.out.println(f1 == f2); 
       System.out.println(f3 == f4);     
} 

这就难怪会f1==f2为true,f3==f4却false了(自动装箱会调用静态方法valueOf)。

感觉这个插件真的好用。对自己养成好的代码习惯一定会很有帮助。(具体怎么安装,根据自己使用的IDE去百度)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,764评论 0 38
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 总说神马浮云,总觉红尘看破,春来春心荡漾,且去菩提打坐。 本是域外自在物,如今开在双桥下,客来踏青赏春色,可知笑靥...
    碧筠小筑阅读 407评论 1 3
  • 一、猫群,一个奇特的存在 的确,里面有几百只各色品种的猫。你在生活中不会经常见到他们,不是因为品种,而是因...
    猎人无忌430阅读 273评论 4 7