不可变类型包装器

时间:2015-06-19 15:25:04

标签: java immutability

我对在执行以下代码

时类型包装器是不可变的感到困惑
static void inc(Integer nr)
{
    System.out.printf("1. inc() \t %d \n", nr);
    nr++;
    System.out.printf("2. inc() \t %d \n", nr);
} // inc()

public static void main(String[] args)
{
    Integer nr1 = 10;
    System.out.printf("a. main() \t %d \n", nr1);
    inc(nr1);
    System.out.printf("b. main() \t %d \n", nr1);
} // main()

执行它会创建以下输出

  a. main()     10 
  1. inc()      10 
  2. inc()      11 
  b. main()     10 

如果类型包装器是不可变的,那么为什么在#34; 1行之间增加值。 INC"和" 2。 INC" 并且排队" b。主"打印与" 1相同的值。主"

谢谢

克里斯

1 个答案:

答案 0 :(得分:2)

  

如果类型包装器是不可变的,那么为什么在#34; 1行之间增加值。 INC"和" 2。 INC"

因为您实际上没有改变现有的Integer对象 - 您正在创建一个新对象(好吧,有效 - 实际上它会使用常见的缓存对象,但重点是nr的值将引用nr++之后的另一个对象。想一想:

nr++;

相反:

int tmp = nr.intValue();
tmp++;
nr = Integer.valueOf(tmp);

因此,您看到nr更改的文本表示并不意味着它所引用的对象已经发生变异 - 在这种情况下,原因是nr本身已经发生了变化在新值上,指的是不同的对象。

您也可以看到更多诊断信息:

static void inc(Integer nr)
{
    Integer original = nr;
    System.out.printf("1. inc() \t %d \n", nr);
    nr++;
    System.out.printf("2. inc() \t %d \n", nr);
    // This will print 10
    System.out.printf("Original: %d\n", original);
} 
  

并且行" b。主"打印与" 1相同的值。主"

引用按值传递,就像它一直一样。这意味着inc(nr1)根本不会修改nr1 - 它指的是之前所做的相同对象。如上所述,inc 不修改对象(因为包装类型是不可变的)。因此,在调用之后,nr1引用包含相同值(10)的相同对象。