Java中的原始包装类是作为参考类型处理的吗?

时间:2014-12-03 22:44:54

标签: java reference wrapper

来自Java in a Nutshell, 2.10 Reference Types

  

Java不直接操作对象和数组。相反,它   操纵对象和数组的引用。因为Java处理   通过引用,类和数组类型的对象和数组被称为   参考类型。相反,Java处理基元的值   直接或按价值类型。

但是从下面看,原始包装类(对象)实际上是由值而不是引用来处理的,

> Integer foo = new Integer(1);
> Integer bar = foo;
> bar = new Integer(2);
> foo
1

上面的引用不是很正确吗?


更新:我的困惑来自误解我上面的代码段与以下内容之间的区别:

> import java.util.LinkedList;
> LinkedList<Integer> foo = new LinkedList<Integer>();
> foo.add(1);
> LinkedList<Integer> bar = foo;
> bar.remove(); 
> System.out.println(foo.size());
0
> System.out.println(bar.size());
0

在后一种情况下,bar.remove()实际上对foobar引用的LinkedList进行操作。

3 个答案:

答案 0 :(得分:1)

原始类包装器是对象引用,而不是基本类型。

在您的示例中,您为变量分配了一个新值,而不是更新状态。这就是为什么foo保留其值(旧的因为它从未更改过)的原因:

Integer foo = new Integer(1);
Integer bar = foo; //bar and foo "points" to the same location
bar = new Integer(2); //now bar only "points" to a new location, foo is unaffected
System.out.println(foo);

您可以使用==equals比较轻松地对此进行测试:

Integer a = 128;
Integer b = 128;
System.out.println(a == b); //false
System.out.println(a.equals(b)); //true

答案 1 :(得分:1)

您的代码片段并未证明包装器的行为类似于值类型:实际上,它们是引用类型,并且它们是不可变的。

Integer foo = new Integer(1); // foo references an object wrapping 1
Integer bar = foo;            // bar references the same object as foo
bar = new Integer(2);         // bar references an object wrapping 2;
                              // continues to reference 1

查看原始包装器会发生什么的一种简单方法是使用==运算符而不是调用equals来比较它们的相等性。但是,您需要小心避免比较小数字的包装器,因为它们是出于性能原因而被缓存的。

答案 2 :(得分:0)

您链接的引用是指字段访问和数组访问表达式。那些需要通过参考值来确定底层对象。

=运算符称为assignment operator.在您的情况下,它不是字段访问表达式,也不是数组访问表达式,因此我们将归入第三种情况

  
      
  • 首先,评估左侧操作数以产生变量。如果此评估突然完成,则为赋值表达式   因同样的原因突然完成;右手操作数不是   评估并且没有分配。
  •   
  • 否则,将评估右侧操作数。如果此评估突然完成,则赋值表达式突然完成   出于同样的原因,没有任何转让。
  •   
  • 否则,将右侧操作数的值转换为左侧变量的类型,进行值集转换   (§5.1.13)到适当的标准值集(不是   扩展指数值集),转换结果是   存储在变量中。
  •   

所以在

bar = new Integer(2);

评估bar并生成变量本身。然后,必须评估new Integer(2)。那是new instance creation expression。它生成一个值为reference value

的实例
  

参考值(通常只是引用)是指向这些的指针   对象,以及一个特殊的空引用,它不引用任何对象。

生成该值后,会将其分配给bar

请注意foo从未参与过。