工作中Integer类型传参遇到的陷阱

遇到的问题

//i = 0
Integer integer=new new Integer(i); 
//i改成4
tempList = this.commonCalMainProcess(list,indexList,integer,position,null); 
//i还是等于0
i = integer;

误区:传对象传的就是地址的引用,所以改变integer的值,它的指向的值也会跟着改变。

一个单元测试

@Test
    public void test02(){ 
        Integer a1 = Integer.valueOf(60);
        Integer b1 = 60;
        System.out.println(System.identityHashCode(a1));
        System.out.println(System.identityHashCode(b1));
        System.out.println("1:"+(a1 == b1));
        System.out.println("------------------");
        Integer a2 = 60;
        Integer b2 = 60;
        System.out.println(System.identityHashCode(a2));
        System.out.println(System.identityHashCode(b2));
        System.out.println("2:"+(a2 == b2));
        System.out.println("------------------");
        Integer a3 = new Integer(60);       //a3--->堆里的地址,常量池中也会有一个60
        Integer b3 = 60;                          //b3---->常量池中的60
        System.out.println(System.identityHashCode(a3));
        System.out.println(System.identityHashCode(b3));
        System.out.println("3:"+(a3 == b3));
        System.out.println("------------------");
        Integer a4 = 127;
        Integer b4 = 127;
        System.out.println(System.identityHashCode(a4));
        System.out.println(System.identityHashCode(b4));
        System.out.println("4:"+(a4 == b4));
        System.out.println("------------------");
        Integer a5 = 128;
        Integer b5 = 128;
        System.out.println(System.identityHashCode(a5));
        System.out.println(System.identityHashCode(b5));
        System.out.println("5:"+(a5 == b5));

    }

输出:

从上边的例子我们可以学习到:

  1. Integer i = new Integer(num);其实是创建了两次对象,一个对象的地址放堆中,一个放常量池中,例如:上边3的输出
  2. 如果i的返回在-127~128内,这个对象可以放到常量池中,所以如果定义的Integer i = 这个范围内,直接引用其地址,其实始就是同一个;但如果超出这个返回,将在常量池中重新创建新的对象,例如:上边4,5的输出
  3. Integer a2 = 60做的其实是Integer a2 = Integer.valueOf(60),自动装箱操作,在-127~128内,如果常量池中有这个对象,它们引用的就是常量池的对象。

通过上述的例子,可以解释遇到的问题

integer指向的是堆中的对象,i在常量池中也有相对应的对象,所以但我们将integer传入函数,并改变它的时候,修改的其实是它在常量池的地址对应的值,所以并不会引起integer真正的改变,因此它还是0!!

解决方案

如果一定要通过函数去修改这个integer的值,有如下方案:

  1. 改变的这个值integer用函数的返回值接收integer = fun();得到就是修改后的值,这个方法的看具体的业务场景。

  2. 自己封装一个 类class MutableInteger{ int value;}这个方法处理麻烦点

  3. 使用AtomicInteger原子整形对象

    AtomicInteger integer=new AtomicInteger(i);
    tempList = this.commonCalMainProcess(list,indexList,integer,position,null);
    int i = integer.intValue();
    
    void commonCalMainProcess(...,AtomicInteger ai...,){ 
    		ai.set(value);
    }
    

 3 total views,  1 views today

页面下部广告