【问题标题】:Passing object reference to a method [duplicate]将对象引用传递给方法[重复]
【发布时间】:2014-05-01 14:16:24
【问题描述】:

如果在 changedetails() 中将 Employee 引用设为 null,则保留变量 id 值并且不抛出 NullPointerException(代码 1)可能是因为我们只是传递了对象引用的副本,但在代码 2 中为什么变量值变了

代码 1:

public class JavaPassing {
    public static void changedetails(Employee e)
    {
        e=null;
    }

    public static void main(String args[])
    {
        Employee emp = new Employee("Vishal",7);
        changedetails(emp);
        System.out.println(emp.id);
    }
}

代码 2:

public class JavaPassing {
    public static void changedetails(Employee e)
    {
        e.id=9;
    }

    public static void main(String args[])
    {
        Employee emp = new Employee("Vishal",7);
        changedetails(emp);
        System.out.println(emp.id);
    }
}

【问题讨论】:

  • 这是事实,问题出在哪里?
  • 根据 SCJP 的书“对方法内部发生的对象的任何更改都将针对其引用被传递的对象进行”。因此,如果我们在方法中将 Employee 对象引用设为 null,那么实际的对象引用也应该设为 null。我在这里错过了什么?

标签: java pass-by-reference pass-by-value


【解决方案1】:

传递给方法changedetails() 的参数是它自己的变量,与main() 方法中的变量emp 不同。他们都指的是同一个员工。因此,如果您引用员工并更改其状态,则更改在changedetails() 和main() 这两种方法中都是可见的。但是,如果您将 null 分配给方法 changedetails() 的参数变量,则这是仅在该方法中可见的局部更改。

旁注:更改方法参数的值被认为是不好的做法。而在离开方法changedetails() 之后,方法参数就消失了,因为它们存在于栈上而不是堆上。

【讨论】:

    【解决方案2】:
    1. 在 java 中,对对象的引用是按值传递的。

    所以,

    public static void main(String args[])
    {
        Employee emp = new Employee("Vishal",7);
        changedetails(emp);  / /object Employee ahs only one reference - "emp"
        System.out.println(emp.id);
    }
    
    
    public void   changedetails(Employee emp1){ // here both emp1 and emp of main() point to the same Employee object.
    emp1.setId(100); // now since emp1 also points to same Employee object, the data will be changed.
    emp1 = null;// now emp1 points to null. So, only emp is pointing to E,ployee
    
    }
    

    【讨论】:

      【解决方案3】:

      In both cases Reference 'e' in changedetails() and 'emp' in main() both point to same object.

      在代码(1)中

      在 changedetails() 中设置 e=null;只有 e 停止指向对象。但是emp继续指向反对。所以在 main() 中,当你打印 emp.id 值并且没有 NullPointerException

      在代码(2)中 在 changedetails() 中,当您使 e.id=9 记住 两个引用都指向同一个对象,即
      changedetails() 中的 'e' 和 main() 中的 'emp' 指向同一个对象.... 所以 e.id=9 意味着对同一个对象所做的更改,因此当您在 main() 中执行 emp.id 时,值为 9

      【讨论】:

        【解决方案4】:
              -------- 
        A -->| Object |<-- B
              --------
        
        A.id = 10; // Property of object modified
        B.id = 10; // Property of object modified here also
        
        B = null ; // B is set to null
              -------- 
        A -->| Object |     B (reference is null)
              --------
        

        此处当您将B 设置为null 时,A 不会被修改,它将继续指向堆中的Object。

        这就是为什么如果您从参考A 访问id,它不会抛出NullPointerException。你所困惑的只是对象的引用和内存中的对象。

        在您的情况下,A 是 emp 和 B 是 e。

        You can find some good explanation in this question.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-20
          • 2016-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多