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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李运岚 中级黑马   /  2014-11-25 09:14  /  3488 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

3黑马币
  1. public class StringDemo {
  2.                 public static void main(String[] args) {
  3.                         String s1 = "java";
  4.                         String s2 = "hello";
  5.                         method_1(s1,s2);
  6.                         System.out.println(s1+"...."+s2); //java....hello
  7.                        
  8.                         StringBuilder s11 = new StringBuilder("java");
  9.                         StringBuilder s22 = new StringBuilder("hello");
  10.                         method_2(s11,s22);
  11.                         System.out.println(s11+"-----"+s22); //javahello-----hello
  12.                 }
  13.                 public static void method_1(String s1,String s2){
  14.                        
  15.                         s1.replace('a','k');
  16.                         s1 = s2;
  17.                 }
  18.                 public static void method_2(StringBuilder s1,StringBuilder s2){
  19.                         s1.append(s2);
  20.                         s1 = s2;
  21.                 }
  22. }
复制代码
这段代码中为什么两个输出语句是那样的结果?有点看不懂,求高手解答一下

最佳答案

查看完整内容

s1.replace('a','k') s1 = s2; s1,s2在方法中属于局部变量接收的是“java” 和“hello”,改变的是形式参数s1的“java”而不是原来s1的“java”,s2桶里~~所以s1还是没有发生改变 s1.append(s2); s1 = s2; 这个方法中s1和s2接收的是容器~形式参数s1接收的是与s11指向同一个容器的地址值~所以在这里s11和s22就被改变了~ ...

12 个回复

倒序浏览
s1.replace('a','k')
s1 = s2;
s1,s2在方法中属于局部变量接收的是“java” 和“hello”,改变的是形式参数s1的“java”而不是原来s1的“java”,s2桶里~~所以s1还是没有发生改变
s1.append(s2);
s1 = s2;
这个方法中s1和s2接收的是容器~形式参数s1接收的是与s11指向同一个容器的地址值~所以在这里s11和s22就被改变了~
回复 使用道具 举报
回答得越详细越好
回复 使用道具 举报
Afridoce 发表于 2014-11-25 11:39
s1.replace('a','k')
s1 = s2;
s1,s2在方法中属于局部变量接收的是“java” 和“hello”,改变的是形式参 ...

补充一下:method_1(s1,s2);这个方法传的不是s1,s2的地址,是“java”和“hello”这两东西不是地址~所以函数外面的s1,s2没有被改变。
回复 使用道具 举报
Afridoce 发表于 2014-11-25 11:42
补充一下:method_1(s1,s2);这个方法传的不是s1,s2的地址,是“java”和“hello”这两东西不是地址~所以 ...

method_2()中的s1 = s2;这一句不是把s2的值赋给了s1吗?为什么s1的值还是javahello
回复 使用道具 举报
李运岚 发表于 2014-11-25 12:00
method_2()中的s1 = s2;这一句不是把s2的值赋给了s1吗?为什么s1的值还是javahello ...

method_2()中的s1 = s2;和method_1()方法中的s1=s2;是一个意思~进行的也是字符串实体的赋值而不是赋值地址~
回复 使用道具 举报
Afridoce 发表于 2014-11-25 12:08
method_2()中的s1 = s2;和method_1()方法中的s1=s2;是一个意思~进行的也是字符串实体的赋值而不是赋值 ...

这样讲你应该比较好理解method_2()的s1 = s2,其实是s2把它在栈内存的地址值赋值给s1而不是吧s22在堆内存的地址值赋值给s11
回复 使用道具 举报
第一部分输出method_1()方法中只是引用了S1,S2。在method_1()方法中其实是重新定义了s1和s2所以对主方法中的s1和s2没有影响
第二部分StringBuilder类型的形参接受的是参数的地址所以操作会影响到main方法的S1,S2。
回复 使用道具 举报
李双 中级黑马 2014-11-25 13:11:37
9#
首先你要明白String 中字符串是个特殊对象,一旦初始化是不能改变的,而Stringbuffer中它的长度是可以变的,虽然你在method_1中对它进行了操作,但是不会改变他的值。但是当你在method_1中对他进行输出,这时结果是改变的,
回复 使用道具 举报
本帖最后由 xiaoxiyang 于 2014-11-25 16:56 编辑

package com.nov25;//我自己创建的包名

public class StringDemo {
    public static void main(String[] args) {
              //对  String s1="java";  的说明  
     /*声明一个字符串类型的对象java,同时我们用变量s1(s1存放在内存的栈中)存放字符串对象java的地址--
               * ---也就是我们常说的将s1指向java, 或者说s1是java的引用。
                   * 为解释方便, 暂时把存放变量s1的区域(栈中的某一小块单独区域)称为a区域,
                   * 实际的数据java在内存的堆中,它也是一块单独的小区域,暂时称为b区域。
                     */
            String s1 = "java";   
            
          //对  String s2="hello";  的说明  ------类似对对  String s1="java";  的说明  
    /*声明一个字符串类型的对象hello,同时我们用变量s2(s2存放在内存的栈中)存放字符串对象hello的地址--
                 * ---也就是我们常说的将s2指向hello, 或者说s2是hello的引用。
                     * 为解释方便, 暂时把存放变量s2的区域(栈中的某一小块单独区域)称为c区域,
                     * 实际的数据hello在内存的堆中,它也是一块单独的小区域,暂时称为d区域。
                       */
            String s2 = "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); //javahello-----hello
    }
   
    //这里说下method_1方法干了哪些事
    public static void method_1(String s1,String s2){  //在主函数中调用method_1方法时要求传入两个String类型的变量,这里是s1,s2。
       s1.replace('a','k');        //s1.replace('a','k')--调用s1的replace方法将字符串s1中所有的字符a替换成字符k,注意是字符a替换字符k。
                                                    //该方法执行完之后产生了新的字符串jkvk,注意是产生了新的字符串,可是你这里没有任何接收jkvk的变量。
                                                      //如果你在s1.replace('a','k');下面再来一行,另设一个变量String s3=s1.replace('a','k');。s3即为jkvk。
          //System.out.println(s1);  //---我这里把s1打印出来,打印s1仍然是java。
            s1 = s2;                //s1=s2做的事----把s2的地址赋值给s1,这样一来,s1的地址和s2的地址是一样的了,
                                                            //即指向的内存堆中的内容都是hello。结果自然是s1="hello",s2="hello"。
                                                            
            //System.out.println(s1);        //我这里把s1和s2也打印出来,以方便做比较,这时s1和s2都是hello。
            //System.out.println(s2);               
    }
   
  //这里说下method_2方法干了哪些事
    public static void method_2(StringBuilder s1,StringBuilder s2){
//在主函数中调用method_2方法时要   求传入两个StringBuilder类型的变量,这里传入的是s11,s22。
s1.append(s2);   //这里要说下StringBuilder类对象的特点,s1.append(s2);是直接在s1指向的内存堆中java的后面直接追加s2所指向的内存堆中的内容hello。
  //此时s1指向的内存堆中的内容就成了javahello,这里并没有产生新的字符串,是在原字符串基础上直接操作,
           //这也是StringBuilder类对象一个很好的特性。并不像String类对象那样会在内存中产生很多对象。
            s1 = s2;       //与method_1方法中s1=s2;类似。
           //System.out.println(s1);   //我这里把s1和s2也打印出来方便比较,这时s1是javahello,s2是hello。
           //System.out.println(s2);
    }
}


中午看到马友们一直在跟帖,有的说的很好,这里贴出来我自己写的和一些说明,个人的一些理解难免有不对的地方,不对的地方希望大家能给指出来。共同讨论一起进步。
回复 使用道具 举报
卤煮用的是苹果电脑么?呵呵
回复 使用道具 举报
method1方法的形参拷贝了实参值,形参指向的值改变不会改变实参;method2中形参是实际是指向实参的地址,指向的值是同一个,所以在方法内可以改变传入实参变量的值。
回复 使用道具 举报
学习这个有长了点知识。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马