public class Example {
String str=new String("good");
char[] ch={'a','b','c','d'};
int i=10;
public static void main(String[] args) {
Example ex=new Example();
ex.change(ex.str, ex.ch,ex.i);
System.out.println(ex.str);
System.out.println(ex.ch[0]);
System.out.println(ex.i);
}
public void change(String str,char[] ch,int n){
str="test ok";
ch[0]='g';
n=9;
}
}
//正确答案是:
//good
//g
//10
那位仁兄能详细地给我分析一下这个题目,怎样理解传值与传地址呢?越详细越好!高分相送,非常感谢!
凑热闹的请走开!
计算机访问数组,实际是通过对数组引用变量的引用,利用数组引用变量所指向的堆内存空间,来访问数组的元素。
而你程序中ch[0]='g';这句话 实际上就是改变了堆内存空间的值
str="test ok";与n=9;这两句话只是新开辟了栈空间存放临时变量
ch指向的内存地址没变,里面的内容变了
ex.str,ex.i都是指向栈内存(值)空间的,而ex.ch则是指向堆内存(地址)空间的,所以ex.str、ex.i传的是值,ex.ch传的是地址,任何时候对数组的操作都是对其指向的地址所指向的值的修改。
str="test ok";//这里的str只是一个形式变量,是str参数的一个副本,所以改变它,不会影响
//原来的参数str,并且在change方法结束之后,该副本就不再被引用;下面的n一样的道理
ch[0]='g';//数组变量存在stack中,而值也就是各元素存在于heap中,变量指向具体的值,所以
//你这句代码指向了heap中的另一个地址,改变了ch数组原来的值了。
n=9;
}
如果说是对对象进行操作,那么就改变了对象的值了
1;对String引用操作,所以不改变其对象的值
2:对数组对象的操作,这里你可能迷糊了,其实ch[0]不是引用,在JVM里,是一条指令根据这个数组引用和索引找到给定数组的指定索引位置的值压入栈,ch[0]相当于ch.get(0),所以是对于ch所指向的对象直接操作,即改变了对象的值
3:n是基本类型,是在change()里的一个临时变量,所以不影响外部的n
str="test ok";
ch[0]='g';
n=9;
}
这里面的String str,char[] ch,int n调用的是参数,函数里面的 str="test ok";
ch[0]='g';
n=9; 也分别是参数 因此不会对类中的变量进行改变,建议楼主测试一个简单的例子public class Example {
int i=10;
public static void main(String[] args) {
Example ex=new Example();
ex.change(ex.i);
System.out.println(ex.i);
}
public void change(int n){
n=9;
}
}输出为10 如果你在函数中change 添加 public void change(int n){
n=9;
System.out.println(n); }
在调用change方法时,会临时分配三个临时变量:str,ch,n。
n是值传递,n的值变为9,但是i不变。ch是数组,是地址传递,所以方法change里面的ch和类ex的ch指向同一个数组:{'a','b','c','d'},故不难理解ex.ch[0]也随之变为g。
那么楼主可能会对String有点疑问。String也是地址传递,字符串的值是放在常量池中的,比如str,当创建good时,发现常量池中没有就在常量池中创建good并把good的地址赋给str,但是请注意这句话:str="test ok";
这句话并不是将str所指向的字符串值good改为test ok,其实是又新建了一个常量 test ok,然后将该字符串的地址赋给change方法中的临时变量str,但是类ex中的sr还是指向原字符串good。这点要非常注意。
change方法里的语句:str="test ok"; 并不是将str所指向的字符串值good改为test ok,其实是又新建了一个常量 test ok,然后将该字符串的地址赋给change方法中的临时变量str,而类ex里的str的值(也就是地址)并没有变,仍然指向原来的字符串值good。
String s = "s";
String s += "d"; //此时的s对象已经和上面的不是一个对象了,在堆中的地址已经改变。
java源码中 不管对String如何操作最后都会返回一个新的String类型要点3:数组为引用类型
而数值就是基本的数据类型才有的传递方式。
ch[0]='g';你把第一个变成了G
n=9;你把值给换个
对不起 没有RETURN你做的全部白做,应为是值传递就像C里面的你换完数不返回不白做么
你这句话只是输出了引用名为str的String,他在内存中的内容不能变,而且你也没有把str指向其他内存块,所以这个str还是老老实实地指向"good",你方法里面
public void change(String str,char[] ch,int n){
str="test ok";
ch[0]='g';
n=9;
}的str是代表另外一个引用,所以你只是把方法里面的引用给了指向"test ok";所以说你原来的main方法那个str还是指向"good"
2. String虽然是一经创建初始化之后就不变,但是跟这里的没有关系,因为change方法里的str只是原始ex.str的一个副本,是个形式参数,在方法change执行完了之后,就会被销毁(不一定是马上)。
我这是用白话讲的,说的不对的地方请大家指教。