将对象传递给方法时出现意外输出

时间:2014-06-04 10:30:17

标签: java

以下代码打印出我意想不到的值;代码打印出50然后19。下面我列出了我的推理,请有人在我的推理过程中纠正错误:

class Wrapper{
    int w = 10;
}

public class Main {
    static Wrapper changeWrapper(Wrapper w){
        w = new Wrapper();
        w.w += 9;
        return w;
    }
    public static void main(String[] args) {
        Wrapper w = new Wrapper(); // line 1
        w.w = 20; // line 2
        changeWrapper(w); // line 3
        w.w += 30; // line 4
        System.out.println(w.w); // line 5
        w = changeWrapper(w); // line 6
        System.out.println(w.w);  // line 7
    }
}

推理过程:

  1. 在第1行,创建一个新的Wrapper对象,w.w的值为10.
  2. 在第2行,w.w的值设置为20.
  3. 在第3行,对w的引用传递给changeWrapper函数。在changeWrapper函数中,创建一个新的Wrapper对象并将其分配给传入的引用。现在,w指向一个新的Wrapper对象,因此w的值为10. Nine被添加到此值,并返回一个对象,w.w等于19. / LI>
  4. 在第4行,添加了30,所以现在w.w是49。
  5. 在第5行,49应该打印出来。
  6. 在第6行,w.w等于49的Wrapper对象传递给changeWrapper方法。在该方法中,将创建一个新的Wrapper对象,并返回一个对象,其值w.w设置为19.然后,此对象的引用将分配给w。所以现在w指向w.w设置为19的对象。因此,19按预期打印出来。
  7. 为什么50打印而不是49?

7 个答案:

答案 0 :(得分:1)

java是按值传递的,因此changeWrapper不会在main方法中使用新的包装器覆盖w。

changeWrapper方法无论如何都不会影响主方法中对包装器的引用。

这将完成您所期望的,仅使用对创建的原始包装器的一个引用:

static Wrapper changeWrapper(Wrapper w){
  w.w += 9;
  return w;
}

当传入w的原始参考时,您可以更改其值。而您的代码只是创建一个新对象的新引用。 顺便说一句,改变你的命名惯例。

答案 1 :(得分:1)

您正在为Wrapper方法中的参数引用分配changeWrapper的新实例并将其返回。

因此,您返回的w的{​​{1}}为Wrapper

这不会更改传递的对象,只会更改方法范围内的引用,当然也不会更改返回的对象。

但是,分配,将19个实例与Wrapper一起返回到w == 19方法的w局部变量。

main删除w = new Wrapper();

概括(主要方法范围内)

  • 第3行对changeWrapper
  • 没有任何作用
  • 第6行将w更改为w.w

答案 2 :(得分:0)

问题在于:

  static Wrapper changeWrapper(Wrapper w){
        w = new Wrapper(); // this line
        w.w += 9;
        return w;
    }

删除此作业,它应该按预期工作

答案 3 :(得分:0)

static Wrapper changeWrapper(Wrapper w){
        w = new Wrapper(); // this line create new refrence of wrapper class so overrise w which you get in method variable
        w.w += 9;
        return w;
    }

答案 4 :(得分:0)

java- References to Objects are passed by Value。所以,

public static void main(String[] args) {
    Wrapper w = new Wrapper(); // line 1. w-->wrapper object
    w.w = 20; // line 2  
    changeWrapper(w); // line 3
    w.w += 30; // line 4
    System.out.println(w.w); // line 5. 20+30=50
    w = changeWrapper(w); // line 6. see method comments
    System.out.println(w.w);  // line 7
}



static Wrapper changeWrapper(Wrapper w){// w(1) and w(2) both point to same wrapper.
        w = new Wrapper();  //w(1)--> original wrapper passed. w(2 i.e, the w in your method)--> new wrapper object
        w.w += 9;
        return w; //returns new wrapper. 
    }

答案 5 :(得分:0)

第3行不是你说的那样!

  

在第3行,对w的引用被传递给changeWrapper函数。   在changeWrapper函数中,创建了一个新的Wrapper对象   分配给传入的参考文献。

确定。

changeWrapper(W); //第3行

  

所以现在,w指向一个新的   包装器对象,因此w的值为10.九是添加到此   返回值和一个对象,w.w等于19。

这是你出错的地方。返回一个实例,但您没有将其分配给w。因此,w仍然指向具有20而不是19的w的旧实例。

答案 6 :(得分:0)

public static void main(String[] args) {
    Wrapper w = new Wrapper(); // line 1
    w.w = 20; // line 2
    w=changeWrapper(w); // line 3 
    w.w += 30; // line 4
    System.out.println(w.w); // line 5 This will give 49
    w = changeWrapper(w); // line 6
    System.out.println(w.w);  // line 7
}

changeWrapper(w); // line 3 
This will not do anything to w

w=changeWrapper(w); // line 3 
Do changes on w