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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 雷丹 中级黑马   /  2013-10-24 22:23  /  2236 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Example{
static String str=new String("good");
static char[] ch={'a','b','c'};
static byte a=120;
public void change(String str,char ch[]){
str="test Ok";
ch[0]='g';
}
public static void main(String[] args){
Example ex=new Example();
ex.change(str,ch);
System.out.print(Example.str+" and ");
     System.out.print(Example.ch);
     
}

}
String传参传的是地址,为什么输出地不是test Ok 呢?

评分

参与人数 1黑马币 +3 收起 理由
狼王 + 3 赞一个!

查看全部评分

8 个回复

倒序浏览
Java中参数传递的确用的是地址传递;
但是String比较特殊,一旦赋值内存里面的内容就不能改变了,
而且String是引用类型的;重新赋值后它指向的地址就改变了,
public void change(String str,char ch[]){  
    str="test ok";  
    ch[0]='g';  
}
ex.change(ex.str,ex.ch);
调用这个方法时,会将ex.str和ex.ch在内存中的地址传递给Str和ch[];他们本身指向的地址没变
执行 str="test ok";  时,change中str指向的地址改变了,但ex.str指向的地址没变;
所以ex.str的值还是String str=new String("good");
  ch[0]='g';会将ch[0]指向的地址的值改变,所以最终ex.change(ex.str,ex.ch);
改变了ch[]的值,但str的值仍然不变

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
new String("good")是在堆内存中的,而str是在栈内存中的,第一次str是指向new String("good")地址,而第二次是将Str指向“test Ok”地址的,根本没有改变new Sting("good")中的值,所以Example.str还是原来的值,说白了你
回复 使用道具 举报
new String("good")是在堆内存中的,而str是在栈内存中的,第一次str是指向new String("good")地址,而第二次是将Str指向“test Ok”地址的,根本没有改变new Sting("good")中的值,所以Example.str还是原来的值,说白了你只是将指向改变了,没改变里面内容的值

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报

  1. /*
  2. 字符串最大的特点在于:一旦被初始化就不可以再被改变;

  3. 并且你代码中的str定义的是静态,它优先于对象存在,所以,调用的就是初始化的Str,
  4. 如果你想要改变str的值,那么用我下面的方法:请在注释部分做修改:
  5. */
  6. class Example
  7. {
  8.          static String str=new String("good");
  9.         static char[] ch={'a','b','c'};
  10.         static byte a=120;
  11.         public String change(String str,char ch[])//将方法的返回值类型写成String,返回另一个str;
  12.                 {
  13.         ch[0]='g';
  14.         return str="test Ok";
  15.                 }
  16.         public static void main(String[] args)
  17.                 {
  18.         Example ex=new Example();
  19.         String str1 = ex.change(str,ch);//这里可以接收,也可以直接在下面打印
  20.         System.out.print(str1+"and");
  21.         System.out.print(ex.ch);
  22.         /*
  23.         System.out.print(Example.str+" and ");
  24.         System.out.print(Example.ch);
  25.                 */
  26.                 }

  27. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报

你的之所以能改变Str的值是因为,栈中的Str变量的指向改变了
回复 使用道具 举报
静态的str (static String str)随类的加载而加载,随类的消亡而消亡,生命周期最长。优先于该类的对象的存在而存在。其存在于常量池中,并不是在堆内存中。
当Example这个类中有static String str时,直接用类名调用的是str,应为这是静态成员的特性。恰好String是常量类,也就是说该类对象一经创建,就不能再改变。

public void change(String str,char ch[]){
str="test Ok";
ch[0]='g';
}
调用change函数,函数中将str赋值"test Ok",这相当于有新new String对象。
通过类名调用的还是原来的静态str=“good”,这就是为什么没有改变的原因

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
我给你解释下不
看我的实例
public class Test {
    static String str=new String("good");
    static char[] ch={'a','b','c'};
    static byte a=120;
    public void change(String str1,char ch1[]){
    str="test Ok";
    ch[0]='g';
    }
    public static void main(String[] args){
    Test ex=new Test();
    ex.change(str,ch);
    System.out.print(Test.str+" and ");
         System.out.print(Test.ch);
         
    }
   
}
运行结果 test Ok and gbc
改变了 你知道说明了什么么
首先  你的str="test Ok"; 是传过来的str 而不是成员变量str
其次传值没错 传过来的 Str1 是个字符串 ch1 是个地址值 你的方法不可以是因为 str传的值不是地址 你改变的只是字符串跟成员变量str没有关系 (一个变量值要想改变就必须改变他的引用 也就是地址值)
在来就是 字符串是final 的是说对象不可以改变 str是对象的引用 可以改变 比如指向一个新对象











评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
王飚 中级黑马 2013-10-25 16:41:04
9#
终结者 发表于 2013-10-25 00:54
你的之所以能改变Str的值是因为,栈中的Str变量的指向改变了

对,就是要改变对象的指向,不然Strring的值初始化就不能改变;
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马