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

Java 将对象传递给方法时出现意外输出,java,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 vo

下面的代码正在打印出我意想不到的值;代码先打印出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行,创建了一个新的包装器对象,w.w的值为10
  • 在第2行,w.w的值设置为20
  • 在第3行,对
    w
    的引用被传递给
    changeWrapper
    函数。在changeWrapper函数中,将创建一个新的包装器对象,并将其分配给传入的引用。现在,
    w
    指向一个新的包装器对象,因此
    w
    的值是10。将九添加到此值,并返回一个
    w.w
    等于19的对象
  • 在第4行,添加了30,因此现在
    w.w
    是49
  • 在第5行,应打印出49
  • 在第6行,将
    w.w
    等于49的包装对象传递给
    changeWrapper
    方法。在该方法中,将创建一个新的包装器对象,并返回一个值为
    w.w
    设置为19的对象。然后将对该对象的引用指定给
    w
    。因此现在
    w
    指向
    w.w
    设置为19的对象。因此,19按预期打印出来

  • 为什么打印出的是50而不是49?

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

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

    这将实现您所期望的,只使用一个对创建的原始包装的引用:

    static Wrapper changeWrapper(Wrapper w){
      w.w += 9;
      return w;
    }
    
    当传入对w的原始引用时,可以更改其值。而您的代码只是创建对新对象的新引用。
    顺便说一句,更改命名约定。

    您正在将
    包装器的一个新实例分配给
    changeWrapper
    方法中的参数引用,并返回它

    因此,返回的
    包装器的
    w
    19

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

    但是,您正在将返回
    Wrapper
    实例的
    w==19
    赋值给
    main
    方法的
    w
    局部变量

    移除
    w=新包装()来自
    changewapper

    重述(主要方法范围)

    • 第3行对
      w
    • 第6行将
      w.w
      更改为
      19
      • 问题在于:

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

        删除此赋值,它应该可以像您在
        java中所期望的那样工作-对对象的引用是通过值传递的。所以

        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;
            }
        
        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. 
            }
        

        第三行没有按你说的做

        在第3行,对w的引用被传递给changeWrapper函数。 在changeWrapper函数中,创建一个新的包装器对象并 分配给传入引用的

        变更包装(w);//第3行

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


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

        好的,我认为Java是通过引用方法传递的。这不是我的命名惯例。这是一个来自Java认证考试的问题。对w的原始引用被传递到方法中,但是它被另一个新的包装器覆盖-主方法中对w的原始引用不受影响。请在此站点上查看java传递值。两个引用一个本地引用来更改包装器,另一个本地引用来更改主对象,并且堆上只有一个对象。当你做新的包装时,你可以在堆上创建第二个对象。干杯
        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