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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© qiubaoyang 中级黑马   /  2014-8-7 16:15  /  3206 人查看  /  25 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 qiubaoyang 于 2014-8-9 13:52 编辑


问题见上图第十行。

点评

十七行 s2=s1;  发表于 2014-8-8 20:59

评分

参与人数 1技术分 +1 收起 理由
格子、 + 1 问的一个好问题,有料

查看全部评分

25 个回复

倒序浏览
图上show方法不是一直在修改s1吗,如果第17行 改为s2=s1,就可以修改s2的值了。
回复 使用道具 举报
你代码中没有对s2进行修改的操作啊,你是想交换s1、s2的值?
回复 使用道具 举报
没动过S2~
回复 使用道具 举报
对s2无操作  自然不会改变
回复 使用道具 举报
我也求解!!!!
我将代码修改了,也不行啊。
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,奇怪了,求高手解答!!!!
回复 使用道具 举报
陶圣虎 发表于 2014-8-7 16:21
图上show方法不是一直在修改s1吗,如果第17行 改为s2=s1,就可以修改s2的值了。 ...

。。。。。

大哥,你先改一下运行看看,到底有没有修改s2的值??
回复 使用道具 举报

是没动过s2,但s1怎么改变了呢???
回复 使用道具 举报
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
        }

}

评分

参与人数 1技术分 +1 收起 理由
格子、 + 1 赞一个!

查看全部评分

回复 使用道具 举报 1 0
席杰 发表于 2014-8-7 22:17
我也求解!!!!
我将代码修改了,也不行啊。
public class Shishi {

show里的s1和main里的s1不是同一个
回复 使用道具 举报
我也来吸收一下经验
回复 使用道具 举报
Joemi 发表于 2014-8-8 20:52
show里的s1和main里的s1不是同一个

show中的第二个s1,也没见自定义,难道它是自动创建的s1吗?他是怎么自动创建的,很奇怪。
回复 使用道具 举报
本帖最后由 烟海 于 2014-8-8 23:06 编辑

刚刚测试了,同样疑问这题,求解。
回复 使用道具 举报
烟海 发表于 2014-8-8 22:49
为何楼上都没有看到重点呢、??

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

但是即使show()函数的返回值为void,主函数打印出s1也为:hellojava,那说明主函数的s1值是改变啊。这说明跟show()函数是否有无返回值无关系。
回复 使用道具 举报
席杰 发表于 2014-8-8 22:53
但是即使show()函数的返回值为void,主函数打印出s1也为:hellojava,那说明主函数的s1值是改变啊。这说 ...

测试了下。。。现在也没理解这题。。。同样求解。。。。
回复 使用道具 举报
席杰 发表于 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其实进行的创建新对象的操作,而不是进行赋值的操作。
你说我分析的对吗?但是我说完,我总感觉有点别扭,我再想那对象的赋值该怎么赋值呢。
回复 使用道具 举报
席杰 发表于 2014-8-8 23:15
我刚又测试了一下,看下面的代码。
public class ShiYan2 {
        public static void main(String[] a ...

正解,长知识了,谢谢了哈
回复 使用道具 举报
烟海 发表于 2014-8-8 23:07
测试了下。。。现在也没理解这题。。。同样求解。。。。

你看看我最后的那个回帖,你看看我说的有理吗?
回复 使用道具 举报
席杰 发表于 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的值没有改变。。。
希望楼主仔细看一看,看看能否看懂???

评分

参与人数 1技术分 +1 收起 理由
格子、 + 1 赞一个!

查看全部评分

回复 使用道具 举报 1 0
烟海 发表于 2014-8-8 23:45
理解的不对。。这里面是传入的两个对方。。s1 s2都是已经建立完成的对象。。。所以show方法里面,不涉及 ...

你现在是在黑马进行培训吗?还是大学学生。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马