class Effect
{
public static void main(String [] args)
{
Effect e=new Effect();
e.method();
}
void method()
{
long [] a1 = {3,4,5};
long [] a2 = doArray(a1);
//expected output
System.out.println("After Calling doArray "+a1[1] +" "+ a2[1]);
String s1 = "Hello";
String s2 = doString(s1);
//expected output s1=HelloJava s2=World like earlier arrays
System.out.println("After Calling doString "+s1 + " " + s2);
}
long [] doArray(long [] a3)
{
a3[1] = 7;
System.out.println("In doArray "+ a3[0]+" "+a3[1]+" "+a3[2]);
return a3;
}
String doString(String s1)
{
s1 = s1 + "Java";
System.out.println("In doString "+ s1);
return "World";
}
}
输出
In doArray 3 7 5
After Calling doArray 7 7
In doString HelloJava
After Calling doString Hello World
我预期的输出:
After Calling doString HelloJava World
请给出一些解释?
答案 0 :(得分:1)
在java String
中,对象是不可变的。
String类是不可变的,因此一旦创建了String 对象无法更改。 String类有很多方法, 其中一些将在下面讨论,似乎修改字符串。 因为字符串是不可变的,所以这些方法真正做的就是创建 并返回一个包含操作结果的新字符串。
代码澄清 -
String doString(String s1) {
s1 = s1 + "Java";
...
}
此处s1+"java"
会在String pool
中创建一个新对象。来自s1
功能的参考method
仍将引用旧的String
对象。
答案 1 :(得分:1)
您需要了解对象和引用(即指针)之间的区别。 对象是真实的(尽可能接近"真实"在程序中)"事物"。 引用只是事物的地址。
如果在电话簿中,我将您家的地址从第一大道123号改为第二大街456号,那么这不会改变您的房屋。它(可能)仍然位于第一大街123号。但如果有人按照电话簿中的地址进行操作,他们最终会在不同的房子中找到。
如果你从一个房子移动到另一个房子你不会(通常)带走房子,你把家具装进一辆卡车(卡车)并把它运到另一个房子里。然后,如果您没有更改电话簿,那么找到您的人将会到达错误的(旧)房屋。
(这与字符串不可变,BTW这一事实无关。long
的数组也是如此。但是你在上面的代码中用数组做的是搬进新家具,不改变地址。只有一个阵列。)
答案 2 :(得分:1)
致电doString(s1);
时
这里s1
是一个本地String引用变量,引用"Hello"
String obj
在此法规s1 = s1 + "Java";
之后
this语句创建一个新的String对象,s1
现在引用" hello java" string obj。
但是在阵列的情况下
doArray()
不创建任何新数组。
答案 3 :(得分:0)
多数民众赞成因为字符串是对字符串变量所做的任何修改都是不可变的,所以它会创建一个新对象。它不会改变您正在操作的对象
当你s1 = s1 + "Java";
时,实际参数仍为Hello
而不是Hello Java
。只有您的形式参数已更改
您可以参考以下链接
您可以找到更详细的解释Click the link
答案 4 :(得分:0)
1)`String s1 = "Hello";
String s2 = doString(s1);
//expected output s1=HelloJava s2=World like earlier arrays
System.out.println("After Calling doArray "+s1 + " " + s2);
2)String doString(String s1)
{
s1 = s1 + "Java";
System.out.println(s1 + " ");
return "World";
}
在第二种情况doString(String s1)
中,您有一个仅适用于doString()
方法的新s1 var,因此只有此方法才能看到您在此方法中所做的更改。它不会反映在method()
内声明的s1 var中。
因此在第二种情况下,您将获得输出为“Hello Java”。 但在第一种情况下,您将获得“Hello”作为输出。声明的s1 var仍指向字符串常量池中的“Hello”字符串。因为,String类在一个不可变的类中。
答案 5 :(得分:0)
s1 = s1 + "Java";
您在上面修改的内容是本地方法。
String s1 = "Hello";
你在这里定义的是,你的方法并不知道声明s1
对你的方法来说是个陌生人。
System.out.println("After Calling doString " + s1 + " " + s2);
< --- s1在此行中声明为字符串,而不是方法中的本地字符串。
更多参考: