class  Test{

public static void main(String[] args) {
String s1 = new String("java"); 
String s2 = new String("hello");
method_1(s1,s2);
System.out.println(s1+"...."+s2); //java....hello

StringBuilder s11 = new StringBuilder("java");
StringBuilder s22 = new StringBuilder("hello");
method_2(s11,s22);
System.out.println(s11+"-----"+s22); 
}
public static void method_1(String s1,String s2){
s1=s1.replace('a','k'); s1 = s2; }
public static void method_2(StringBuilder s1,StringBuilder s2){
s1.append(s2); s1 = s2; }
}

解决方案 »

  1.   

    method1调用后无变化,method2调用后有变化。字符串类型在java里是一种特殊类型,类似于int等基本类型。method1传的是值,method2传的是引用。
      

  2.   


    我怎么误导了,应该不会啊,我虽没用运行,但是觉得理论上应该是的啊。
    method1调用后,应该不变,这个应该没有异议。
    method2调用后,s1.append(s2);这一句肯定会改变s1的值,但是s1 = s2;并不会改变s2,所以打印出来应该是java hello hello,hello会被重复一次。
    我想应该是这样。
      

  3.   

    字打错了,应该是"但是s1 = s2;并不会改变s1和s2,"
      

  4.   

    方法1中,接收了两个引用,这个引用指向了一个对象,拿s1举例,我们假设这个对象的地址是0001,s1被重新赋值过,(也就是=过)这时,s1就指向了新地址0002,可是0001里面还是原来的对象。
    然后方法执行完了之后,方法内的s1没了,可是外面的s1还是指向的0001。而0001里面还是原来的字符串。方法2中,接收的也是两个引用,拿s1举例,s1.append(s2);会直接对0001这个地址进行操作,这样的话0001里面的字符串就变了,第二行s1=s2,这个局部的s1的引用就指向了s2的引用,比如是0003,然后方法返回,局部的s1和s2都销毁了,方法外输出的时候,0001里的对象已经变了
      

  5.   

    那方法一中,
    s1=s1.replace('a','k');
    这个操作怎么没有效果?
      

  6.   

    字符串类型和int等基本类型是有差别的
      

  7.   

    输出结果为
    java....hello
    javahello-----hello
      

  8.   


    这个操作其实是有效果的,在method_1()方法内你用System.out.println()语句将s1和s2打印出来可以验证s1和s2被"暂时"改变了,只是在调用此方法之后,该方法占用的内存会被释放,也就是说,传参数的时候是传的一份原变量s1和s2的拷贝,所以对原变量无影响,楼主如果有c语言的基础应该这些能够理解
      

  9.   


    照着这么说s1=s1.replace('a','k');这一句应该起作用吧
    s1指向的对象已经改变了,把a变成k
    可结果却没有哦
      

  10.   

    字符串类型和int等基本类型是有差别的
      

  11.   

    String是final类型,即内容不可改变。s1=s1.replace('a','k');这句话的结果是新开辟了一个内存空间,用于存放“jkvk”,而原始的“java”并未改变。
    但是StringBuilder就不一样了,是可变类型,可以直接对它所指向的内存空间修改内容。
      

  12.   

    //得先说说赋值语句:String s1 = new String("java"); 相当于给了一个箱子1,这个箱子1的钥匙是s1,这个箱子1里放了个苹果,"java"就是这个苹果,而这个箱子1就是内存中的一块。
    //接下来method_1(s1,s2);这个方法调用的意思就是新配了一把钥匙s1,这个钥匙也能开上面那个箱子1,这是引用传递,但由于string是不变对象,是值传递,所以method_1(s1,s2)(引用传递就理解为新配一把钥匙,值传递就理解为把箱子里的东西复制一份放到另外的箱子里面)
    //传给参数s1的不是钥匙,而是苹果。意思就是有了另外一个箱子2,钥匙是参数s1,箱子2里也有个苹果。而method_1里面的s1=s1.replace('a','k');改变的是箱子2里的苹果。箱子1里面的
    //东西根本没变,而method_1(s1,s2);调用的作用域在main函数里,main函数里的s1是指第一个箱子,所以第一个输出java....hello。这样就不难理解method_2了。method_2(s11,s22);
    //这个方法调用是指给箱子3 s11配了把钥匙s1,给箱子4 s22配了把钥匙s2(因为stringbuffer是引用传递,不是string那样的值传递),method_2函数里的s1.append(s2);这句话表明用s1
    //这把钥匙打开箱子3,给他加了个梨。现在箱子3里就有梨和苹果了(javahello),s1=s2这句话就是把s1这把钥匙打磨下能打开箱子4了,就不能打开箱子3了。但是注意,箱子3的原配钥匙s11并
    //没有变化,还是打开箱子3,现在变的是箱子3里面的东西。method_2(s11,s22);这个方法调用的作用域在main方法里,所以s11打开箱子3(javahello),s22打开箱子4(hello)输出结果是
    //javahello----hello
      

  13.   

    楼上关于箱子和钥匙的比喻很形象啊,哈哈。但是我不太清楚java里面是不是只有值传递,这一点不太确定。
      

  14.   

    我又网上查阅了一下,感觉JAVA里面还是只有值传递,不过分为两种情况:
    1)对于int、float等八种基本类型的对象,传递的是他本身的内容值(箱子里面的苹果)
    2)对于String、定义的类等其他类型的对象,传递的是他在内存中的地址值(箱子的钥匙)
    建议看一看这位仁兄的论述和代码http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html
      

  15.   

    大家能帮我把这两句画个图不?
         如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
        如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。
      

  16.   

    坐等高手说明。个人认为
    这个说法比较靠谱一点。但是没有说完全。比如 s1.append(s2);得到了javahello。
    那s1 = s2 这个为什么后面没有变成hello。
      

  17.   

    代码改成:
    class  Test{public static void main(String[] args) {
    String s1 = new String("java"); 
    String s2 = new String("hello");
    method_1(s1,s2);
    System.out.println(s1+"...."+s2); //java....helloStringBuilder s11 = new StringBuilder("java");
    StringBuilder s22 = new StringBuilder("hello");
    method_2(s11,s22);
    System.out.println(s11+"-----"+s22); 
    }
    public static void method_1(String s1,String s2){
    s1.replace('a','k');s1 = s2;}
    public static void method_2(StringBuilder s1,StringBuilder s2){
    s1.append(s2);s1 = s2;}
    } 结果是一样的,
    而且s1.replace('a','k')指向的是同一个内存区,只是replace()方法没有改变结果。越来越糊涂了,请解答一下,谢谢!
      

  18.   

    我运行了,method_1没有改变,method_2改变了
      

  19.   

    因为String是字符串类型,指向的引用相当于常量,不能被改变吧,,,有问题希望高手帮忙指点!
      

  20.   

    java....hello
    javahello-----hello
    String类的对象不可以对内容进行动态的操作,比如删减增加字符
    method——1中s1 = S2 只是对地质进行了赋值而没有对字符串内容进行改变所以不能改变内容
    而StringBuilder是一个可变的字符序列类 ,和StringBuffer都是对字符串进行动态操作的类所以可以改变内容
      

  21.   

    String是mutable类型,做为参数传入方法时是传值,所以第一个方法不改进传进去的String。
    StringBuilder不是mutable类型,所以做为参数传入方法时是传引用(java的引用概念和C++不太一样),所以第二个方法会改变传入的值
      

  22.   


    s1 = s2 这个和s1.append(s2)不一样,s1 = s2;是引用传递,方法执行完,效果就没了。我在图中有画的。
      

  23.   

    谢谢,我已经弄懂了。和String有关系。
      

  24.   

    String和StringBuilde的区别,String 定义的变量是不可变的,StringBuilde是可以进行操作的