这是我在StackOverflow的第一个问题。这是有问题的代码:
public class ListStuff {
public static void main(String [] args) {
String[] randomNames = {"Herbie", "Jaco", "Pat", "Michael"};
String[] reversedNames = revertNames(randomNames);
for (int i = 0; i < reversedNames.length; i++) {
System.out.println(reversedNames[i]);
}
}
public static String[] revertNames(String[] s) {
for (int i = 0; i < s.length / 2; i++) {
String tmp = s[s.length - 1 - i];
s[s.length - 1 - i] = s[i];
s[i] = tmp;
}
return s;
}
}
此代码运行良好,reversedNames
变量打印为已恢复;没有抱怨。然而,我主要担心的是,当我执行String[] reversedNames = revertNames(randomNames);
时,变量randomNames
也会被还原。我没做任何地方用randomNames
改变randomNames = blabla;
变量,所以我不明白为什么该变量不断变换为自身的恢复版本,即使我只是将它作为参数传递。
我已经编程了大约一年,而且我对变量范围的了解非常有限。有人能指出我正确的方向吗?
答案 0 :(得分:7)
Java中的数组是引用类型。这意味着当您将数组传递给revertNames
方法时,该方法内部的任何更改也将在外部看到。由于您要使用以下代码更改s
内的数组参数revertNames
:
String tmp = s[s.length - 1 - i];
s[s.length - 1 - i] = s[i];
s[i] = tmp;
代替randomNames
传递的原始数组s
也会在此过程中发生变化。
答案 1 :(得分:3)
这是因为您通过引用而不是按值传递数组。从本质上讲,这意味着reversedNames
数组仍然指向randomNames
数组,因此更改一个数组会改变另一个数组。
以下是变量图:
最初:
randomNames
当我们输入revertNames
函数时:
randomNames <-------- s
s
数组仍然指向randomNames
数组!因此,当我们更改s
时,我们也会更改randomNames
。
当我们离开这个职能部门时:
randomNames <--------- s <--------- reversedNames
因此,reversedNames
指向randomNames
。
函数调用完成后:
randomNames <--------- reversedNames
虽然s
数组已消失,但reversedNames
仍指向randomNames
。
要解决此问题,请在revertNames
函数中创建一个临时变量:
public static String[] revertNames(String[] oldarray) {
// Create temporary array to avoid affecting original array
String[] s = oldarray.clone();
...
答案 2 :(得分:1)
在revertNames的主体中,你有一个变量s,这是对一个数组的对象的引用。实际的数组是数组randomNames。所以你确实在改变源数组中的值。
如果你使用Arrays.copy()你可以得到一个独立的数组 - 副本将指向与原始数组相同的字符串,但是因为字符串是可以安全的,所以
答案 3 :(得分:0)
您可以使用:StringBuffer:reverse()
有些事情是这样的:
public class t {
public static void main(String [] args) {
String[] randomNames = {"Herbie", "Jaco", "Pat", "Michael"};
StringBuffer rev;
for (int i = 0; i < randomNames.length; i++)
{
rev=new StringBuffer(randomNames[i]);
System.out.println(rev.reverse().toString());
}
}
}
答案 4 :(得分:0)
Java中的数组是引用类型,即如果声明
String[] randomNames;
您已声明一个局部变量,该变量包含对作为字符串数组的对象的引用。
声明
String[] otherNames = randomNames;
会将变量randomNames的内容复制到变量otherNames,但内容只是一个引用。也就是说,此语句会导致otherNames和randomNames引用同一个数组对象。
当您传递String[]
作为方法参数时,会发生同样的情况。也就是说,s
中的局部变量revertNames
和randomNames
中的局部变量main
将包含相同的引用,即引用相同的数组对象。也就是说,虽然s
和randomNames
都可以看到该数组对象的状态。
严格来说,这与范围无关,因为变量randomNames
未被修改(即它仍然指向同一个数组)。修改的是它引用的对象。