zoukankan      html  css  js  c++  java
  • 小心Java中封装类的值比较

        一般我们使用数值时,都是使用基本类型,如int、long等,但如果你喜欢使用Integer、Long的包装类,那有一点可就得注意了。先来看下这段代码:

    /**
     * 
     * @author trytocatch@163.com
     * @date 2014-2-12
     */
    public class AutoBoxingTest {
        public static final Integer CONST_A = 1;
        public static final Integer CONST_B = Integer.valueOf("2");
        public static final Integer CONST_C = new Integer(3);
        
        private Integer status;
        
        public void setStatus(Integer status){
            this.status = status;
        }
        
        public void displayStatus(){
            if(status == CONST_A)
                System.out.println("It's CONST_A");
            else if(status == CONST_B)
                System.out.println("It's CONST_B");
            else if(status == CONST_C)
                System.out.println("It's CONST_C");
            else 
                System.out.println("Invalid status!");
        }
        
        public static void main(String[] args) {
            AutoBoxingTest abt = new AutoBoxingTest();
            abt.setStatus(1);
            abt.displayStatus();
            abt.setStatus(2);
            abt.displayStatus();
            abt.setStatus(3);
            abt.displayStatus();
        }
    }

        执行结果是(jre版本:1.7.0_10):

    It's CONST_A
    It's CONST_B
    Invalid status!

        可能有人会奇怪,为什么第三个不输出It's CONST_C呢?其实jre挺懒的,如果发现==两边都是对象,它就直接比较引用,而不是值,跟普通对象一样,因为status为3的那次比较中,两边是两个不同的对象,所以不相同。而前两个为什么可以呢?是因为IntegerCache的存在,在自动装箱(给CONST_A赋值和setStatus(int)时)和调用Integer.valueOf(String)时,返回的Integer有时(为什么说是有时?是因为IntegerCache只对部分数值做了缓存,具体请阅读源码)是从Cache中获取的,所以都是同一个对象,而CONST_C在赋值时是我们自己new出来的,所以跟Cache中的对象不是同一个。

        延伸一下,如果一边是包装类,一边是基本类型时;或者使用了<、>、<=等比较符,都会进行值比较。只有刚好满足引用比较的条件时,jre才会偷懒,直接进行引用比较。所以,定义常量变量时,最好使用基本类型,使用==和!=时多多留意。

    ps:文章比较短,我不喜欢重复在网上随便都能搜到的东西,像装箱拆箱,封装等。如果本文对你有帮助,还请支持一下


    再啰嗦几句,可能没细看的读者会觉得,不就是说==比较的是引用么,有什么好讲的?我说下我写此文的考虑,因为平时可能习惯了直接对封装类使用<、>、<=等,使用==时也没出问题(上面的例子中CONST_A和CONST_B那两种情况),想当然的认为封装类不会进行引用比较,这种观念也许会在编码中埋下隐患,如果你将CONST_A的值改为10000,你会发现又不对了。

  • 相关阅读:
    还敢说你是程序员?一律师闲着没事写了个app,用户量600万
    cnentos中进行bond网卡配置,一切配置无问题,就是ping不通宿主机
    他曾被腾讯、百度、金山、遨游等联合封杀,如今他发展的却更好
    百度命不久矣?他为什么这么说?
    html实现下拉框、switch开关、复选框效果
    javascript拖拽滑动条
    行内元素默认间距的4种解决办法
    Html5 video用法详解
    npm装包时-S和-D的区别
    css3实现背景模糊的三种方式
  • 原文地址:https://www.cnblogs.com/trytocatch/p/3545244.html
Copyright © 2011-2022 走看看