将字符串传递给函数
我想问一个非常简单的问题。我只是将一个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:为什么这样工作?字符串是一个对象。为什么我需要另一个包装对象来更改对象!如果我想通过引用传递某些东西会怎么样?那可能吗?
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.
}
做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!";
}
}
是,爪哇通过引用传递类参数。不可能告诉它以其他方式做。
您可以将字符串包装到另一个类中或使用库中的StringBuilder
。
P.S.
str =“HERE”;
只是将旧引用替换为指向" HERE"
的新引用。这不会触及函数外部的旧引用str。
P.P.S.
也许我的术语是错误的。所以,简单地说,String类型的Java变量包含对该字符串的引用。该引用被传递到函数中。赋值正在改变一个引用,而不是原始对象。
它通过值传递,而不是引用。 – Max 2012-02-07 21:01:42
Java是通过引用传递的。例如,函数可以修改StringBuilder。当然,参考本身是通过价值传递的。 – 2012-02-07 21:08:02
字符串在Java中是不可变的。为了这个工作,你需要从hangeString方法返回新创建的字符串实例。
static String changeString(String str)
{
return " HERE";
}
你混合的东西你也有同样的问题,因为你有没有包装。 虽然这两个变量被称为“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
Java正在处理所有复杂类型的引用。字符串和所有使用的定义类型都由引用表示。你可以把引用看作一个你无法访问的C++指针。 – 2012-02-07 21:14:54
@salamis Remeber Java永远是传值!形式参数(这是方法changeString中的str)只是指向内存位置的引用的副本,其中“Hello!”是。因此,当您现在指定“HERE”而不是指向“Hello!”时指向“这里”,而原始的不变。 “HERE”将被垃圾收集。 – MalsR 2012-02-07 21:22:02