为什么包装类对象的标识符不能用作引用变量

时间:2013-08-23 12:49:50

标签: java autoboxing

我的问题涉及包装类。我知道当我们使用包装类存储基本类型文字时,我们将它存储为该包装类的对象,因此对象的标识符将是一个引用变量(在某种程度上类似于c ++中的指针)。例如,在Integer wi = new Integer("56")中,wi是参考变量。但如果这是真的:

  1. 为什么我可以wi++wi +=2?为什么编译器会处理那些像普通原始变量这样的引用变量?参考变量不存储对象的引用吗?

  2. 鉴于Integer wi = new Integer("56")int pi = 56,为什么(wi == pi)会返回true。是不是应该存储引用(地址)?

  3. 另一个问题:当一个引用变量作为参数传递给方法时,它计为通过引用传递,因此发生的修改 该参考变量应该影响它的值,但它不会:

    public class Main {
      void show(Integer x){
        x *=100 ;
      }
    
      void goo(int x){
        x *=100 ;
      }
    
      public static void main(String[] args) {
        Main mn = new Main() ;
        Integer wi = new Integer("86");
        int pi = 86 ;
    
        mn.goo(pi);
        System.out.println(pi); //output = 86
    
        mn.show(wi);
        System.out.println(wi); //output = 86, shouldn't it be 8600?
      }
    }
    

4 个答案:

答案 0 :(得分:4)

语句mn.goo(pi)传递值86的副本,而mn.show(wi)传递包含相同对象的引用变量副本。

  
      
  1. 为什么我能这样做? wi ++或wi + = 2 .i意味着为什么编译器会处理像普通原始变量这样的引用变量?(不是引用变量存储对象的引用?)
  2.   

由于autoboxingauto-unboxing的概念,wi转换为primitive,递增,然后转换回Wrapper

  

2.或如果我们有==>“整数wi =新整数(”56“)”和“int pi = 56”。为什么(wi == pi)返回true。不应该存储引用(地址)

这是因为对于Integer包装类,==将为值128返回true。这是设计

如果您对passign原语和对象引用有疑问,请研究这些程序

class PassPrimitiveToMethod
{
    public static void main(String [] args)
    {
        int a = 5;
        System.out.println("Before Passing value to modify() a = " + a);
        PassPrimitiveToMethod p = new PassPrimitiveToMethod();
        p.modify(a);
        System.out.println("After passing value to modify() a = " + a);
        // the output is still the same because the copy of the value is passed to the method and not the copy of the bits like in refrence variables
        // hence unlike the reference variables the value remains unchanged after coming back to the main method

    }   


    void modify(int b)
    {
        b = b + 1;
        System.out.println("Modified number  b = " + b);
        // here the value passed is the copy of variable a
        // and only the copy is modified here not the variable 
    }       

}

输出

Before Passing value to modify() a = 5
Modified number  b = 6
After passing value to modify() a = 5

将对象引用传递给方法

class PassReferenceToMethod
{
    public static void main(String [] args)
    {
        Dimension d = new Dimension(5,10);
        PassReferenceToMethod p = new PassReferenceToMethod();
        System.out.println("Before passing the reference d.height = " + d.height);
        p.modify(d);            // pass the d reference variable
        System.out.println("After passing the reference d.height = " + d.height);
        // the value changes because we are passing the refrence only which points to the single and same object
        // hence the values of the object are modified 
    } 

    void modify(Dimension dim)
    {
        dim.height = dim.height + 1;
    }   


}

输出

class PassReferenceToMethod
{
    public static void main(String [] args)
    {
        Dimension d = new Dimension(5,10);
        PassReferenceToMethod p = new PassReferenceToMethod();
        System.out.println("Before passing the reference d.height = " + d.height);
        p.modify(d);            // pass the d reference variable
        System.out.println("After passing the reference d.height = " + d.height);
        // the value changes because we are passing the refrence only which points to the single and same object
        // hence the values of the object are modified 
    } 

    void modify(Dimension dim)
    {
        dim.height = dim.height + 1;
    }   


}

输出

Before passing the reference d.height = 10
After passing the reference d.height = 11

答案 1 :(得分:1)

java编译器会自动插入intValueInteger.valueOf调用,以便在intInteger之间进行转换。例如,以下是问题的代码段:

void show(Integer x){
  x *=100 ;
}

以下是真正发生的事情:

void show(Integer x) {
  int unboxed = x.intValue();
  unboxed *= 100;
}

如您所见,行x *= 100并未真正更改您传入的Integer对象,它只会更改从int对象中提取的Integer值。

以类似的方式,问题中的代码wi == pi实际上意味着wi.intValue() == pi,这可以解释您的观察结果。

答案 2 :(得分:0)

Java使用“按值调用”概念,如详细描述here 所以在你的情况下x * = 100;在方法show中只更新局部变量

答案 3 :(得分:0)

编译器将wi解包为原始数据类型。现在,它是一种原始数据类型,因为Java中的所有内容都是按值传递的,正式参数中的更改不会影响实际的争论。

mn.show(wi);