【问题标题】:How are objects passed to a method in java (by value Or by reference)? [duplicate]对象如何传递给java中的方法(通过值或通过引用)? [复制]
【发布时间】:2012-09-07 21:49:17
【问题描述】:

可能重复:
Is Java “pass-by-reference”?

我想知道如何通过java中的引用将对象作为参数传递给方法。 我试过这段代码

public class Class1 
{
    public Class1()
    {
        String x = null;
        F(x);
        //x = null
        System.out.println("x = " + x);
    }

    void F(String x)
    {
        x = "new String";
    }

    public static void main(String[] args)
    {
        new Class1();
    }
}

您可以看到我将 String 传递给函数 F 并在其中更改了 String 的值,但在函数 F 之外我看不到我对其所做的更改。当我执行此代码时,我得到了//{x = null} 这不是我所期望的 //{x = new String}

【问题讨论】:

    标签: java


    【解决方案1】:

    对象本身是通过引用传递的,而reference是通过值传递的。

    这意味着您可以更改函数中的对象,即您可以更改它们的字段、调用对象上更改其状态的方法等。

    您正在尝试更改函数中的 reference。该参考只是一个副本。

    还要注意String 是不可变类型。所以即使有它的引用,你也不能改变底层的Object

    【讨论】:

    • 是的,在这种情况下,字符串在 Java 中是不可变的。所以你实际上是从字符串池中取回对新字符串对象的引用。
    • @tuğrulbüyükışık String 上没有 set 方法
    • @pb2q 也许 .concat("sdfdsfsd") 有效
    • RE第一句:对象根本不传递,如果我们要区分对象和引用(我们必须解释区别)。最重要的是,没有什么比传递引用更远,因为尽管也使用了术语“引用”,但它并不是指传递称为引用的东西,而是传递对存储位置的引用>(变量、数组元素、对象字段等)..
    【解决方案2】:

    Java 通过值而不是引用传递参数。见我的answer on another question for an explanation by figures

    但是,您可以通过以下方式实现您的目标:

    1- 使用数组:

    public class Class1 
    {
        public Class1()
        {
            String x = null;
            String[] holder = {x};
            F(holder);
            //x = null
            System.out.println("x = " + holder[0]);
        }
    
        void F(String[] holder)
        {
            holder[0] = "new String";
        }
    
        public static void main(String[] args)
        {
            new Class1();
        }
    }
    

    2- 使用包装类:

    class WrapperClass
    {
        public String value;
    }
    
    public class Class1 
    {
        public Class1()
        {
            String x = null;
            WrapperClass w = new WrapperClass();
            w.value = x;
            F(w);
            //x = null
            System.out.println("x = " + w.value);
        }
    
        void F(WrapperClass wrapper)
        {
            wrapper.value = "new String";
        }
    
        public static void main(String[] args)
        {
            new Class1();
        }
    }
    

    【讨论】:

      【解决方案3】:

      Java 对象通过引用传递。意味着当您创建一个对象并将其分配给一个引用(变量)时,它的地址被分配给它。当您在被调用的函数中修改它时,它会修改传递的同一个对象。但在您的情况下,您传递了与任何对象无关的 null。

      请参阅我的示例以获得清晰的想法。

      public class Class1 {
      public Class1() {
          StringBuffer x = new StringBuffer("Before");
          F(x);
          // x = null
          System.out.println("x = " + x);
      }
      
      void F(StringBuffer x) {
          x.append("After");
      }
      
      public static void main(String[] args) {
          new Class1();
      }
      

      }

      【讨论】:

        【解决方案4】:

        自从 Java 诞生以来,字符串就是一种“特殊”的对象。 它们确实存在于堆上,但为了节省内存和提高性能,JVM 将保留相同字符串的计数,并将所有引用指向具有相同值的位置。但要使其正常工作,内存中的字符串必须是不可变的(冻结,它们不能再更改)。

        另一种方法是修改您的代码,以便您的函数返回更新后的值:

        public class Class1 
        {
            public Class1()
            {
                String x = null;
                x = F(x);
                //x = null
                System.out.println("x = " + x);
            }
        
            String F(String x)
            {
                return x = "new String";
            }
        
            public static void main(String[] args)
            {
                new Class1();
            }
        }
        

        但也许你传递一个参数是有原因的,这只是为了说明你的方法如何返回一个新的字符串。

        【讨论】:

          【解决方案5】:

          你不能这样做,因为 sting 是不可变的,是不可改变的。你可以使用 StringBuffer 它是可变的。ok

          class One
          {
              One()
              {
                  StringBuffer x =new StringBuffer("null");
                  F(x);
                  //x = null
                  System.out.println("x = " + x);
              }
          
              void F(StringBuffer x)
              {
                  x = x.delete(0,4);
                  x=x.append("new string");   
              }
          
              public static void main(String[] args)
              {
                  new One();
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2011-09-27
            • 2011-04-19
            • 2012-05-20
            • 2021-08-19
            • 2018-04-03
            相关资源
            最近更新 更多