考虑以下代码中的第2行和第3行......
class ModifyObjects {
static void modifyString1(String s){
s = "xyz";
//Or any other operations
}
static String modifyString2(String s){
s = "xyz";
return s;
//Or any other operations
}
static void modifyPrimitive1(int i){
i=9;
}
static int modifyPrimitive2(int i){
i=9;
return i;
}
}
public class Operations {
public static void main(String[] args) {
// TODO Auto-generated method stub
String st1 = "abcd";
String st2 = "qwerty";
String st3;
int i1=0, i2;
st1 = "xyz"; //line 1
System.out.println("st1: " + st1);
ModifyObjects.modifyString1(st2);
System.out.println("st2: " + st2); //line 2
st3 = ModifyObjects.modifyString2(st2);
System.out.println("st3: " + st3);
System.out.println("st2: " + st2);
ModifyObjects.modifyPrimitive1(i1);
System.out.println("i1: " + i1); //line 3
i2 = ModifyObjects.modifyPrimitive2(i1);
System.out.println("i2: " + i2);
}
}
第2行给出st2为qwerty(不修改。应该是xyz。) 第3行给出i1 = 0(不修改。应该是9。)
这看起来有点奇怪。这是输出:
st1: xyz
st2: qwerty
st3: xyz
st2: qwerty
i1: 0
i2: 9
同样在第1行创建了一个新的字符串对象“xyz”吗?我认为“abcd”就是从这里引用的。
答案 0 :(得分:3)
在Java中对对象的引用按值传递......
1. st1: xyz
Reason : you are not returning anything...
2. st2: qwerty
Reason :You are not storing the returned value in st2. you should do,
st2=ModifyObjects.modifyString1(st2);
3. st3: xyz
reason : You are returning a String value and storing it in st3
4. st2: qwerty
Reason : st2 is qwerty...
5. i1: 0 // Not reassigning value to anything
6. i2: 9 // returned value reassigned to i2.
答案 1 :(得分:1)
我认为你对java中字符串和参数传递的工作方式有些困惑。
1)字符串是按设计不可变对象,因此一旦构建就无法更改。为了清楚起见,这样的事情:
String s = "a";
s += "bc";
System.out.println(s);
不是修改String的值,而是创建新对象。在此代码的末尾,您创建了2个String对象:第一行中值为“a”的对象,第二行中值为“abc”的对象。 (这是一种自愿的简化,因为java编译器可能决定优化此代码,但无论如何它都是正确的)
2)如果您需要一个可变的String对象,java会为您提供StringBuilder
对象(如果您需要同步版本,则为StringBuffer
)。如果你需要将东西附加到String,它实际上是推荐的习惯用法。
3)参数传递在java中始终按值;这意味着使用赋值左侧的参数将永远不会在方法调用之外产生影响;相反,您只需踩到您收到的参数的值。如果参数是基本类型或对象类型,则无关紧要。如果参数是对象类型,则参数传递也是值,但是复制到方法调用堆栈的是对象引用的副本。所以,在你的modifyStringXX
方法中,你唯一能做到的就是踩参数,但你永远不会看到那些方法之外的效果。