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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 常佳杰 中级黑马   /  2012-6-26 09:46  /  2734 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class Output {
  2.         public static void LET(String str){
  3.         str="b";
  4.         System.out.println("第二次str="+str);//[color=Blue]这儿打印的是b,说明 又把b赋值给了str1,[/color]
  5.                                              //[color=Blue]String为不可变对象,一旦被创建,就不能修改它的值,这儿怎么就改了呢?[/color]
  6.    }
  7.         public static void main(String[] args) {
  8.                 // TODO Auto-generated method stub
  9.                         String str1="a";
  10.                         System.out.println("第一次str="+str1);
  11.                         LET(str1);
  12.                         System.out.println("第三次str="+str1);
  13.         }   
  14. }
  15. //打印结果是:
  16. 第一次str=a
  17. 第二次str=b
  18. 第三次str=a
复制代码
请详解..

11 个回复

倒序浏览
这个问题貌似之前有兄弟已经问过了,答案:

java基本类型及其包装类采用值传递,对于对象采用引用传递。虽然string不是java里的基本类型,但是他同样不是按引用传递。
看一下API,不会找到能够改变String对象的方法。任何输出上的改变都是重建新的String对象,而不是在原对象基础上改变。改变的是变量的内容,即,不同对象的引用。

你方法内的str 和main方法里的其实是两个对象。
回复 使用道具 举报
http://bbs.itheima.com/thread-17851-1-1.html
你的问题和上面的帖子一样的道理·!
回复 使用道具 举报
本帖最后由 陆强强 于 2012-6-26 09:59 编辑

字符串是不可变的,但指向字符串的引用型变量的指向是可以变的。就像你去超市买东西,“a”,"b"就放在超市,你不能改变,但拿什么由你决定
回复 使用道具 举报
例如String s1="1";String s2=s1;
如果你改变了s1="2",那么s2仍然等于1
原因是它重新开辟一个新的空间,里面装的是2,s1指向这个新的空间。
所以说string一旦被赋值就不可以改变的原因就在这里
回复 使用道具 举报
public class Output {

        public static void LET(String str){
  //2 这里你实际上是改变了str1的引用。它不再指向“a”而指向了"b";这个时候,对象“a”并没有被改变;
  //只是str1不在指向它了;过程如下;
  //str1作为参数被传递;str=str1;
  //str="b";
  //这里执行一系列动作都没有对对象"a"和“b”任何改变;
  //改变是都只是它的们引用;而你的打印语句不都是在打印引用str1或str指向的对象吗;
        str="b";

        System.out.println("第二次str="+str);//这里打印的是引用被修改后的值;即str1指向了“b”;所以会输出“b”;

   }

        public static void main(String[] args) {

                // TODO Auto-generated method stub

                        String str1="a";

                        System.out.println("第一次str="+str1);//这里的str1是一个引用,它指向对象“a”; 所以输出为"a";

                        LET(str1);//1 这是的str1原本是指向对象"a"的,

      //上面说到str1的对象被修改;但str1在方法中存在;是一个局部变量;他的作用域仅在使用它的方法中;
      //所以LET()方法对str1引用的修改对于主函数main()没有影响;所以这是时候的str1仍然指向了“a”
      //所以下面的输出结果就为“a”了;
                        System.out.println("第三次str="+str1);

        }   
}

//打印结果是:

第一次str=a

第二次str=b

第三次str=a
回复 使用道具 举报
其实 你定义一个 String对象并将值设为a,这就好像String有一个pool一样,在这个pool当中创建了一个String对象 并将该对象的引用赋给了str,当你调用方法之后,将str的引用指向了b那么输出的肯定是b里面存放的值了,你调用方法的时候只是将str的一个拷贝传给了形参,所以你在方法内部的调用等方法结束之后就失效了 所以还是a
回复 使用道具 举报
其实 你定义一个 String对象并将值设为a,这就好像String有一个pool一样,在这个pool当中创建了一个String对象 并将该对象的引用赋给了str,当你调用方法之后,将str的引用指向了b那么输出的肯定是b里面存放的值了,你调用方法的时候只是将str的一个拷贝传给了形参,所以你在方法内部的调用等方法结束之后就失效了 所以还是a
回复 使用道具 举报
其实给你举个例子 你就明白了  我们声明一个变量 String s = "Hello world!";
我们到底声明了什么?回答通常是:一个String,内容是“Hello world!”。这样回答是不准确的,其实
这个语句声明的是一个指向对象的引用,名为“s”,可以指向类型为String的任何对象,目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:
  String string = s;
  我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象


  只有当你使用new关键字的时候,我们才在堆里面创建了一个对象
回复 使用道具 举报
例如String s1="1";String s2=s1;
如果你改变了s1="2",那么s2仍然等于1
原因是它重新开辟一个新的空间,里面装的是2,s1指向这个新的空间。
所以说string一旦被赋值就不可以改变的原因就在这里

你说的和我问的相同呀哥们,
String str1="a";String str=str1;str=“b”;为什么这样可以?
回复 使用道具 举报
public static void LET(String str){
        str="b";//这里的"a"是一个对象."b"是另外一个对象 并不是把"a"改成"b了"  而是str指向的对象发生了变化  
        System.out.println("第二次str="+str);
   }
回复 使用道具 举报
LET(str1)只是把 a的地址传进了方法,也就是给了str1
str1 在方法内,是一个局部变量,str1=“b“,把 b的地址赋值给str1,str1由原来的指向 a变为指向 b
但是,整个过程 str1 一直指向 a,str1的值没有改变。
所以打印结果是
第一次str=a
第二次str=b
第三次str=a
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马