将字符串传递给函数

时间:2012-02-07 20:51:50

标签: java

我想问一个非常简单的问题。我只是将一个String对象传递给一个函数,但结果很奇怪。我认为因为我传递一个对象(通过引用),结果应该是“Here”而不是“Hello”。为什么会这样?

public class MainStr
{

/**
 * @param args
 */
public static void main(String[] args)
{
    String str = "Hello!";
    System.out.println(str);
    changeString(str);
    System.out.println(str);


}

static void changeString(String str)
{
    str=" HERE";
}

}

感谢。

编辑:

public class MainStr
{

String str;
/**
 * @param args
 */
public static void main(String[] args)
{
    MainStr ms = new MainStr();
    ms.str = "Hello!";
    System.out.println(ms.str);
    changeString(ms);
    System.out.println(ms.str);


}

static void changeString(MainStr ms)
{
    ms.str=" HERE";

}

}

如果是这种情况,那么为什么我将它传递给包装器对象呢?包装器对象不是通过引用?

PS:为什么这样做? String是一个对象。为什么我需要另一个包装器Object来更改OBJECT!如果我想通过引用传递内容怎么办?这可能吗?

6 个答案:

答案 0 :(得分:7)

Java通过值传递对象引用,这意味着当您调用函数时,会发生以下情况。

 String origStr = "Some String"

 // origStr -> "Some String "

当对象传递给值时,它看起来像这个

 //origStr -> "Some String " <- passedStr

然后在函数中重置passStr指向

的内容
 //origStr -> "Some String "
 //passedStr -> "Other String"

原始字符串仍然引用“Some String”,但它的副本现在引用“Other String”

从函数返回时,原始字符串引用仍指向“Some String”

//编辑:为什么你可以修改另一个对象引用的对象?

假设我有StringWrapper,它是一个包含字符串的类。

对于看起来像这样的

origStr -> strWrpA -> "Some String"

当您将其传递给函数时,会发生以下情况

origStrWrp -> strWrpA -> "Some String"
passedStrWrp --/^

注意两个变量如何指向内存中的strWrpA。 现在,如果我决定修改strWrpA.myString Java将 按照指向包装器中实际字符串的指针。指针 到strWrpA将保持不变。 这意味着我可以改变对象的内容 我正在通过原始参考文献的副本访问它。

                        "Some String "
origStrWrp -> strWrpA -> "I got Changed!"
passedStrWrp --/^

如果你这样做,你会遇到和没有包装器一样的问题

//Does Nothing
function (origStrWrp)
{
origStrWrp=new StringWrapper("Other String") // This only reassigns the copy of the reference and would give you the same problem
}
//Changes internal object
function (origStrWrp)
{
origStrWrp.myString = "Other String" // This doesn't change the reference, it changes the object that it refers to.
}

答案 1 :(得分:4)

在Java中,引用按值传递。这是popular SO discussion以理解这个主题。引用str的范围仅限于changeString方法,因为将引用作为值传递。

答案 2 :(得分:2)

字符串在Java中是不可变的。为了使其工作,您需要从hangeString方法返回新创建的字符串实例。

static String changeString(String str)
{
    return " HERE";
}

答案 3 :(得分:0)

执行str=" HERE";实际上会更改str指向的对象。它不会更改原始对象。如果要修改原始文件,请将其放在包装器对象中。

示例:

public class MainStr {

    static class StringWrapper {
        public String str;
    }

    public static void main(String[] args) {
        StringWrapper foo = new StringWrapper();
        foo.str = "Hello!";
        System.out.println(foo.str);
        changeString(foo);
        System.out.println(foo.str);
    }

    static void changeString(StringWrapper str)
    {
        str.str = "Bye!";
    }
}

答案 4 :(得分:0)

是的,Java通过引用传递类参数。无法告诉它采取其他方式。

您可以将字符串包装到另一个类中,或者使用库中的StringBuilder

<强> P.S。

str =“HERE”;

只是将旧引用替换为指向" HERE"的新引用。这不会触及函数外的旧参考str。

<强> P.P.S。

可能我的术语错了。因此,简单来说,String类型的Java变量包含对该字符串的引用。该引用传递给函数。分配正在改变参考,而不是原始对象。

答案 5 :(得分:0)

你正在混合东西。 虽然这两个变量都被称为'str',但它们处于不同的“范围”

第一个只在方法中有效 而第二个只在 changeString 方法中有效。

似乎您希望实现使用 changeString main 方法中进行更改的目标;你必须:

a)在方法之外创建一个变量 - 这样它就会有一个类(全局)范围:

喜爱 分享[g +]分享[fb]分享[tw]

我想问一个非常简单的问题。我只是将一个String对象传递给一个函数,但结果很奇怪。我认为因为我传递一个对象(通过引用),结果应该是“Here”而不是“Hello”。为什么会这样?

public class MainStr
{
String str = null;

public static void main(String[] args)
{
    str = "Hello!";
    System.out.println(str);
    changeString();  // there is no argument to supply
    System.out.println(str);


}

static void changeString()
{
    str= str + " HERE"; // variable is changed here
}

}

b)启用changeString以返回字符串,并使用:

public class MainStr 
{

/**
 * @param args
 */
public static void main(String[] args)
{
    String str = "Hello!";
    System.out.println(str);
    str = changeString(str);   // str has return value assigned to it!
    System.out.println(str);   // otherwise it would print out 'Hello!'


}

static String changeString(String str)
{
    str = str.concat(" HERE");
    return str;

}
}

注意: 在第二个选项(b)中,您仍然有两个具有不同范围和相同名称的变量。

而在第一个选项(a)中,整个

中只有一个变量

希望这能澄清你的怀疑。

祝你好运!

尼古拉斯