将字符串传递给函数

将字符串传递给函数

问题描述:

我想问一个非常简单的问题。我只是将一个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:为什么这样工作?字符串是一个对象。为什么我需要另一个包装对象来更改对象!如果我想通过引用传递某些东西会怎么样?那可能吗?

+0

Java正在处理所有复杂类型的引用。字符串和所有使用的定义类型都由引用表示。你可以把引用看作一个你无法访问的C++指针。 – 2012-02-07 21:14:54

+0

@salamis Remeber Java永远是传值!形式参数(这是方法changeString中的str)只是指向内存位置的引用的副本,其中“Hello!”是。因此,当您现在指定“HERE”而不是指向“Hello!”时指向“这里”,而原始的不变。 “HERE”将被垃圾收集。 – MalsR 2012-02-07 21:22:02

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

String origStr = "Some String" 

// origStr -> "Some String " 

当对象被传递给它看起来像这样

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

然后在功能重置什么passedStr点

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

原始字符串还是指“值一些字符串“,但它的副本现在引用”其他字符串“

当您返回时m函数原始字符串引用仍指向“一些字符串”

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

可以说我有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. 
} 
+0

为什么这不会发生与其他对象? – glarkou 2012-02-07 21:02:29

+0

是什么让你觉得它不是? – RussS 2012-02-07 21:03:26

+0

因为如果我使用包装对象它的工作。我可以发布一些代码,如果你想! – glarkou 2012-02-07 21:04:22

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!"; 
    } 
} 
+0

如果只有'字符串是可变的... – 2012-02-07 20:55:58

+0

@他不可变有一些好处:http://stackoverflow.com/questions/3407403/whats-the-advantage-of-a-string-be-immutable – mtsz 2012-02-07 20:58:31

+0

@他通过“修改”我的意思是把它设置为别的东西(即改变它指向的对象,而不是内部数据) – jli 2012-02-07 20:59:41

是,爪哇通过引用传递类参数。不可能告诉它以其他方式做。

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

P.S.

str =“HERE”;

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

P.P.S.

也许我的术语是错误的。所以,简单地说,String类型的Java变量包含对该字符串的引用。该引用被传递到函数中。赋值正在改变一个引用,而不是原始对象。

+2

它通过值传递,而不是引用。 – Max 2012-02-07 21:01:42

+0

Java是通过引用传递的。例如,函数可以修改StringBuilder。当然,参考本身是通过价值传递的。 – 2012-02-07 21:08:02

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

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

在Java引用中按值传递。这里是popular SO discussion来理解这个话题。引用str的作用域仅限于将引用作为值传递给changeString方法。

+0

请检查编辑的问题。 – glarkou 2012-02-07 21:09:56

+0

还值得在萨拉米斯上面的链接阅读;)这很有趣。你会发现这个链接有帮助http://javadude.com/articles/passbyvalue.htm?repost – MalsR 2012-02-07 21:57:07

你混合的东西你也有同样的问题,因为你有没有包装。 虽然这两个变量被称为“STR”他们是在不同的“范围”

第一只是你主要方法 内有效,而第二只是你changeString方法内有效。

看来,如果你想完成你的使用changeString使主要方法中可用的变化的目标;你必须:

一)创建方法之外的变量 - 这样就会有一个类(全球)范围:

喜爱 份额[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 
} 

} 

二)让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)只有一个,在整个

希望这阐明你的疑惑变量。

祝你好运!

Nicolas