黑马程序员技术交流社区

标题: 关于StringBuilder的一些问题 [打印本页]

作者: qiubaoyang    时间: 2014-8-7 16:15
标题: 关于StringBuilder的一些问题
本帖最后由 qiubaoyang 于 2014-8-9 13:52 编辑


问题见上图第十行。

作者: 陶圣虎    时间: 2014-8-7 16:21
图上show方法不是一直在修改s1吗,如果第17行 改为s2=s1,就可以修改s2的值了。
作者: 新语新空    时间: 2014-8-7 18:56
你代码中没有对s2进行修改的操作啊,你是想交换s1、s2的值?
作者: Joemi    时间: 2014-8-7 20:18
没动过S2~
作者: liqiaohui    时间: 2014-8-7 21:51
对s2无操作  自然不会改变
作者: 席杰    时间: 2014-8-7 22:17
我也求解!!!!
我将代码修改了,也不行啊。
public class Shishi {
        public static void main(String[] args) {
                StringBuilder s1=new StringBuilder("hello");
                StringBuilder s2=new StringBuilder("java");
                toTrim(s1,s2);
                System.out.println(s1+"...."+s2);//打印结果为:hellojava....java
        }
        public static void toTrim(StringBuilder s1,StringBuilder s2) {
                s1.append(s2);
                s2=s1;
        }
}
但是我在主函数中进行s2=s1,确可以,可以将s1值赋给s2,奇怪了,求高手解答!!!!
作者: qiubaoyang    时间: 2014-8-8 12:37
陶圣虎 发表于 2014-8-7 16:21
图上show方法不是一直在修改s1吗,如果第17行 改为s2=s1,就可以修改s2的值了。 ...

。。。。。

大哥,你先改一下运行看看,到底有没有修改s2的值??
作者: qiubaoyang    时间: 2014-8-8 12:38
Joemi 发表于 2014-8-7 20:18
没动过S2~

是没动过s2,但s1怎么改变了呢???
作者: Joemi    时间: 2014-8-8 20:43
qiubaoyang 发表于 2014-8-8 12:38
是没动过s2,但s1怎么改变了呢???

是这样的,StringBuffer在JDK文档中有这样一句:线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
所以show这个方法,第一句调用了append,改变了s1的内容,是hellojava;在第二句,这个s1内容确实变成了java,但这个s1和main()里的s1不是同一个,你在这里下个断点,就可以看到,他们的地址是不同的,这个是show方法创建的。另外你还可以设置个全局的变量来验证:
public class test_stringbuffer {
       
        public static StringBuffer s=null;//设置一个全局变量

        public static void main(String[] args) {
                StringBuffer s1=new StringBuffer("hello");
                StringBuffer s2=new StringBuffer("java");
                show(s1,s2);
                System.out.println(s1+"......"+s2);       //输出hellojava......java
                System.out.println(s);                       //输出Java
        }

        private static void show(StringBuffer s1, StringBuffer s2) {
                s1.append(s2);
                s1=s2;       //可以在这里下个断点,你就看明白了
                s=s1;        //给全局变量赋值,这里s1确实是java
        }

}
作者: Joemi    时间: 2014-8-8 20:52
席杰 发表于 2014-8-7 22:17
我也求解!!!!
我将代码修改了,也不行啊。
public class Shishi {

show里的s1和main里的s1不是同一个
作者: lcycr    时间: 2014-8-8 20:57
我也来吸收一下经验
作者: 席杰    时间: 2014-8-8 22:49
Joemi 发表于 2014-8-8 20:52
show里的s1和main里的s1不是同一个

show中的第二个s1,也没见自定义,难道它是自动创建的s1吗?他是怎么自动创建的,很奇怪。
作者: 烟海    时间: 2014-8-8 22:49
本帖最后由 烟海 于 2014-8-8 23:06 编辑

刚刚测试了,同样疑问这题,求解。
作者: 席杰    时间: 2014-8-8 22:53
烟海 发表于 2014-8-8 22:49
为何楼上都没有看到重点呢、??

这题的重点在show() 这个函数的返回值为void 。为空。。

但是即使show()函数的返回值为void,主函数打印出s1也为:hellojava,那说明主函数的s1值是改变啊。这说明跟show()函数是否有无返回值无关系。
作者: 烟海    时间: 2014-8-8 23:07
席杰 发表于 2014-8-8 22:53
但是即使show()函数的返回值为void,主函数打印出s1也为:hellojava,那说明主函数的s1值是改变啊。这说 ...

测试了下。。。现在也没理解这题。。。同样求解。。。。
作者: 席杰    时间: 2014-8-8 23:15
席杰 发表于 2014-8-8 22:49
show中的第二个s1,也没见自定义,难道它是自动创建的s1吗?他是怎么自动创建的,很奇怪。 ...

我刚又测试了一下,看下面的代码。
public class ShiYan2 {
        public static void main(String[] args) {
                StringBuilder s1=new StringBuilder("hello");
                StringBuilder s2=new StringBuilder("java");
                toTrim(s1,s2);
                System.out.println(s1+"...."+s2);//打印结果为:hellojava....java
        }
        public static void toTrim(StringBuilder s1,StringBuilder s2) {
                s1=s1.append(s2);
                System.out.println(s1);//输出hellojava
                s2=s1;
                System.out.println(s1);//输出hellojava
                System.out.println(s2);//输出hellojava
        }
}
你看看我分析的对吗?
首先咱们要明确,咱们操作的是类对象,而不是基本数据类型的简单赋值操作。
在show方法中,s1=s1.append(s2);是对主函数传入的s1对象本身的操作,因为这是对象自己调用自己append方法进行的,所以不涉及创建新的对象,还是本身对象的操作。
而第二步中s2=s1,其实是进行了从新创建对象的操作,其实质为StringBuffer s2=new StringBuffer("hellojava");因为s1是一个对象,而不是数值,而咱们是以赋值的思想考虑的。
所以s2=s1其实进行的创建新对象的操作,而不是进行赋值的操作。
你说我分析的对吗?但是我说完,我总感觉有点别扭,我再想那对象的赋值该怎么赋值呢。
作者: paozhuanyinyu    时间: 2014-8-8 23:25
席杰 发表于 2014-8-8 23:15
我刚又测试了一下,看下面的代码。
public class ShiYan2 {
        public static void main(String[] a ...

正解,长知识了,谢谢了哈
作者: 席杰    时间: 2014-8-8 23:26
烟海 发表于 2014-8-8 23:07
测试了下。。。现在也没理解这题。。。同样求解。。。。

你看看我最后的那个回帖,你看看我说的有理吗?
作者: 烟海    时间: 2014-8-8 23:45
席杰 发表于 2014-8-8 23:15
我刚又测试了一下,看下面的代码。
public class ShiYan2 {
        public static void main(String[] a ...

理解的不对。。这里面是传入的两个对方。。s1 s2都是已经建立完成的对象。。。所以show方法里面,不涉及到新建对象的。。。

刚刚和我们班里面的小伙伴们探讨了一下。得到了答案。。我整理下说出来,看看你能不能看懂。。。

最初的时候,这个show()方法里面, s1=s1.append(s2);  s2=s1; ,

有这两个,这里面append方法,
是在常量池进行操作的,直接找到了s1,然后StringBuffer是一个容器,
这儿找到这个容器,然后往里面放了个字符串s2 ,
这个直接在常量池修改的,就相当于修改s1本身,,所以s1本身被修改了,再把s1打印出来,,自然也就是修改后的s1了。。
而后面s1= s2 ,或者我测试的时候,改成s2 = s1 ,这样执行的结果其实是一致的,看起来,好像这一行都没有执行。。。其实这一行是执行的了,只是这个是赋值,是在栈内存中执行的,执行完成之后,如果方法内,有输出语句,就把赋值后的字符串打印出来,而如果没有输出语句,则看是否有return方法,如果有return方法,则把需要返回的值,返回出去。。
而这里是void类型,又没有返回值,所以这儿赋值后的s1 ,没有被返回,然后这时候show()方法执行完毕,栈内存被释放了,而这里s1没有被返回,所以s1 还是append修改后的值。。。s2还是没变化。。这儿s2 = s1 ,把s1赋值给s2 ,也是一样的,没有返回值,赋值的东西,在栈内存,执行完show()方法,就被释放了,所以s2的值没有改变。。。
希望楼主仔细看一看,看看能否看懂???
作者: 席杰    时间: 2014-8-9 00:11
烟海 发表于 2014-8-8 23:45
理解的不对。。这里面是传入的两个对方。。s1 s2都是已经建立完成的对象。。。所以show方法里面,不涉及 ...

你现在是在黑马进行培训吗?还是大学学生。
作者: 烟海    时间: 2014-8-9 00:41
席杰 发表于 2014-8-9 00:11
你现在是在黑马进行培训吗?还是大学学生。

在传智的基础班。。。为了考黑马。。。
因为觉得自学进度太慢。。。黑马的视频班当时又没赶上。。就来传智了。。
刚刚是和基础班的同学探讨了一下。。
目前打算考43期的黑马呢。。。
作者: qiubaoyang    时间: 2014-8-9 13:49
烟海 发表于 2014-8-8 23:45
理解的不对。。这里面是传入的两个对方。。s1 s2都是已经建立完成的对象。。。所以show方法里面,不涉及 ...

懂了,谢谢你。:lol
作者: qiubaoyang    时间: 2014-8-9 13:51
Joemi 发表于 2014-8-8 20:43
是这样的,StringBuffer在JDK文档中有这样一句:线程安全的可变字符序列。一个类似于 String 的字符串缓 ...

谢谢你!
作者: 烟海    时间: 2014-8-9 22:30
qiubaoyang 发表于 2014-8-9 13:51
谢谢你!

不用客气。。。
共同进步吧 。。。。。

这一题还有个升级版。。。更复杂。。。

等等我整理发出来。。。。
作者: qiubaoyang    时间: 2014-8-10 13:32
烟海 发表于 2014-8-9 22:30
不用客气。。。
共同进步吧 。。。。。

恩恩。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2