A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© a844468138 中级黑马   /  2014-1-6 12:20  /  1572 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 a844468138 于 2014-1-6 20:23 编辑

class Test{
String str=new String("good");
char[] ch={'a','b','c'};
public static void main(String[] args){
  Test t=new Test();
  t.change(t.str,t.ch);
  System.out.println(t.str);
  System.out.println(t.ch);
}
public void change(String str,char ch[]){
  str="test.ok";
  ch[0]='g';
}
}

为什么结果会是
good
gbc
为什么str的值没变,而ch的值会变

评分

参与人数 1技术分 +1 收起 理由
FFF + 1 神马都是浮云

查看全部评分

8 个回复

倒序浏览
在调用t.change(t.str, t.ch);语句后,发生了这么几件事:1.change进入栈内存,拿到一块空间,在空间里创建了两个局部变量并根据传来的参数进行了初始化:
                        String str =t.str;----------------------注意,str是局部变量,这一步传过来的是个地址值。
                              char[] ch = t.ch;---------------------同样,ch也是局部变量,接收到的也是个地址。
2.执行chang方法里的语句,首先执行str = "test.ok";此时,这个动作其实是把值赋给了局部变量str,并没有改变t.str的值。这时,两个局部变量的值变成了这样
                              String str = "test.ok";----------------------注意,str是局部变
                              char[] ch = t.ch;---------------------同样,ch也是局部变


3.然后执行ch[0] = 'g';由于是按地址引用,所以会改变t.ch[0]的值,后面两个元素的值不变。

4.change执行return,回到main方法,然后接着执行下面的语句!
----------------------------------啦啦啦,我是分割线-----------------------------------------------------------------------------------------
解决方案一:
               换个变量名,比如这样
  1. class Test {
  2.         String str = new String("good");
  3.         char[] ch = { 'a', 'b', 'c' };

  4.         public static void main(String[] args) {
  5.                 Test t = new Test();
  6.                 t.change(t.str, t.ch);
  7.                 System.out.println(t.str);
  8.                 System.out.println(t.ch);
  9.         }

  10.         public void change(String hehe, char ch[]) {
  11.                 hehe = "test.ok";
  12.                 ch[0] = 'g';
  13.         }
  14. }
复制代码
解决方案二(推荐):
               使用this关键字,用于和局部变量区分!
  1. class Test {
  2.         String str = new String("good");
  3.         char[] ch = { 'a', 'b', 'c' };

  4.         public static void main(String[] args) {
  5.                 Test t = new Test();
  6.                 t.change(t.str, t.ch);
  7.                 System.out.println(t.str);
  8.                 System.out.println(t.ch);
  9.         }

  10.         public void change(String str, char ch[]) {
  11.                 this.str = "test.ok";
  12.                 ch[0] = 'g';
  13.         }
  14. }
复制代码




点评

我后来也是用的第二个方案  发表于 2014-1-6 13:26

评分

参与人数 2技术分 +2 黑马币 +2 收起 理由
FFF + 2 赞一个!
a844468138 + 2 赞一个!

查看全部评分

回复 使用道具 举报
你的change()方法改变的只是传入的参数的值,而内存中的String的值并没有改变,而为什么ch[0]的值变了呢?那是因为你传入的是t.ch,它本身是个指针,指向的就是内存中的ch数组,所以方法中对它做的改变在内存中是生效的.你可以试着这样改写代码:

class Test{
String str="good";
char[] ch={'a','b','c'};
public static void main(String[] args){
  Test t=new Test();
  t.change(t);
  System.out.println(t.str);
  System.out.println(t.ch);
}
public void change(Test t){
  t.str="test.ok";
  t.ch[0]='g';
}
}



个人拙见,仅供参考,如有错误,还望赐教。

评分

参与人数 2技术分 +1 黑马币 +2 收起 理由
FFF + 1 赞一个!
a844468138 + 2 淡定

查看全部评分

回复 使用道具 举报
沙发上的第一个方案是不行的,跟方法的参数名无关,第二个方案确是一个挺不错的方法。
回复 使用道具 举报
  1. package com;
  2. class Test1{
  3. String str=new String("good");
  4. char[] ch={'a','b','c'};
  5. /*public static void main(String[] args){
  6.   Test1 t=new Test1();
  7.   t.change(t.str,t.ch);
  8.   System.out.println(t.str);
  9.   System.out.println(t.ch);
  10. }*/
  11. /*public void change(String str,char ch[]){
  12.   str="test.ok";
  13.   ch[0]='g';
  14. }
  15. }*/
  16. //为什么str的值没变,而ch的值会变?因为String是类类型,是引用类型,初始化值不变,变的是变量。
  17. //那么如果你想打印"test.ok";需要这样做

  18. public static void main(String[] args){
  19.   Test1 t=new Test1();
  20.   t.change(t.str,t.ch);

  21.   System.out.println(t.ch);
  22. }
  23. public void change(String str,char ch[]){
  24. String s ="test.ok";
  25. ch[0]='g';
  26. System.out.println(s);
  27. }
  28. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
FFF + 1 很给力!

查看全部评分

回复 使用道具 举报
你的str 局部变量 不会影响全局的

this.str="test.ok"这样就会变了!!!
回复 使用道具 举报
因为字符串是不可变的 而数组的元素是可以重新赋值的
回复 使用道具 举报
遇到引用传递的情况,如果不容易一下看明白,可以自己尝试画图,那样可以帮助你快速理解

引用传递.gif (32.21 KB, 下载次数: 6)

引用传递.gif
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马