1

可能的重复:
Java 是“按引用传递”吗?

我想知道如何通过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();
    }
}

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

4

5 回答 5

9

对象本身是通过引用传递的,但该引用是通过值传递的。

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

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

另请注意,这String是一个不可变类型。所以即使有它的参考,你也不能改变底层的Object.

于 2012-09-14T17:44:37.090 回答
2

Java 通过值而不是引用传递参数。有关数字解释,请参阅我对另一个问题的回答

但是,您可以通过以下方式实现您想要做的事情:

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();
    }
}
于 2012-09-14T17:54:15.200 回答
2

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();
}

}

于 2012-09-14T18:03:56.820 回答
1

从 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();
    }
}

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

于 2012-09-14T21:04:44.683 回答
0

你不能这样做,因为 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();
    }
}
于 2012-09-14T18:35:05.493 回答