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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

package day1109;

public class Demo {
       
         public static void main(String []args){
                 String s1=new String("abc");
                 
                 String s2 =new String("XYZ");
                 show(s1,s2);
                 System.out.println(s1+"-------"+s2);
         }
         public static void show(String s1,String s2){
                 s1=s1+s2+"Q";
                 s2="W"+s1;
         }
}


//运行结果:abc-------XYZ

//懵了,字符串对象是引用型,为什么执行函数show后,s1,s2没改变。

//关于函数的执行后对参数照成的影响,深入点的讲解。有特殊的最好,最怕出到特殊题。。。

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

11 个回复

倒序浏览
字符串是常量,一旦定义就不能更改了。
所谓引用传递就是把对象的引用地址传进函数,而不是像值传递那样产生一个副本,对于字符串对象来说,虽然在参数传递的时候也是引用传递,但是java虚拟机在函数内部对字符串对象进行了特殊处理--视String对象为常量(final) 所以对传进来的引用地址所引用的string对象不能直接进行修改,而是产生一个副本对其进行操作,对其进行的操作不会影响原来的值。
所以出现了上面的结果,产生一个副本,但s1指向的还是原来abc的地址,打印当然是abc了

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
你好,首先说你对局部变量和全局变量掌握的不好,我认为是这样,其实你完全可以把String换成int类型,试一下:比方说:如下代码
        public static void main(String []args){
                int s1=100;
               
                int s2 =200;
                show(s1,s2);
                System.out.println(s1+"-------"+s2);
        }
        public static void show(int s1,int s2){
                s1=s1+s2+300;
                s2=500+s1;
        }

运行结果是100-------200,


关于局部变量和全局变量我就不给你做过多的解释了,我告诉你一个技巧吧,就是一个变量起作用的范围不会超过离他最近的一对{},(static 和final除外),也就是说你在show里定义的s1和s2不会影响main里的s1和s2,两个s1其实在栈内存里完全是两个不同的地方,当然不会互相影响。
如果你想得到你要的结果,那么就必须把show的值用return传给main方法。
        public static void main(String[] args) {
                String s1 = new String("abc");
                String s2 = new String("XYZ");

                s1 = show1(s1, s2);
                s2 = show2(s1, s2);
                System.out.println(s1 + "-------" + s2);
        }

        public static String show1(String s1, String s2) {
                s1 = s1 + s2 + "Q";
                s2 = "W" + s1;
                return s1;
        }

        public static String show2(String s1, String s2) {
                s1 = s1 + s2 + "Q";
                s2 = "W" + s1;
                return s2;
        }

运行结果为
abcXYZQ-------WabcXYZQXYZQ


其实这个问题是好多同学遇到的问题,我记得以前学C语言的时候我们班的得有一大半搞不懂形式参数,实际参数,全局变量和局部变量,java还好,没有可操作的指针,C语言用可操作的指针传参,班里也就有几个像我这样大师级的人物才能理解上去,哈哈哈哈,不好意思自夸一下!!!

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1

查看全部评分

回复 使用道具 举报
补充一点啊,虽然String不是基本数据类型,在堆内存会有引用位置,不过我们只要把它当成基本数据类型就好了。
回复 使用道具 举报

java不同于c/c++,没有所谓的引用传递和地址(指针)传递,从概念上看,java中的引用概念类似于c/c++中的指针概念,但是java不支持对于引用变量自身的直接操作,所以java中的引用也就只能操作所指对象了,这种问题分析一下内存分配过程就一目了然了.show函数的s1和s2在调用完show之后消失了,所以没有对main产生任何影响.

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

回复 使用道具 举报
其实简单一句话,把String当做基本数据类型就好了,其他的都是浮云。
回复 使用道具 举报
Lucking 发表于 2013-11-10 14:50
java不同于c/c++,没有所谓的引用传递和地址(指针)传递,从概念上看,java中的引用概念类似于c/c++中的指针概 ...

public class Demo {
        public static void main(String[] args) {
                Demo2 demo1 = new Demo2();
                demo1.i = 1;
                Demo2 demo2 = demo1;
                demo2.i = 2;
                System.out.println(demo1.i);         
        }

}

class Demo2 {
        int i;
}

那你看看这段代码输出为啥是2呢??
我觉得任何一种语言都是相通的,java并非没有指针,只是不允许操作指针罢了。
我觉得楼主的问题其实只要考虑String类型虽然是引用类型,但是我们要把它当做基本数据类型来用就好了,其他的就算再怎么了解底层,对于目前的开发来说应用也是不大的。
回复 使用道具 举报
Lucking 中级黑马 2013-11-10 20:58:24
8#
轩辕迪卡 发表于 2013-11-10 16:19
public class Demo {
        public static void main(String[] args) {
                Demo2 demo1 = new Demo2();

java的引用实质上就是c/c++的指针概念,但是java的参数传递都是通过实参的拷贝来传递的,所以java中只有所谓的值传递,你的代码里完全没有自定义函数调用,哪里来谈传递的概念哈,这位童鞋~~,你这单纯就是把demo1和demo2两个引用变量指向同一个对象而已啊,当然操作哪个引用都能改变i喽.我所说的跟你上面的解释貌似也没什么冲突,但是参数传递的方式java有且仅有一种,就是传值.
回复 使用道具 举报
Lucking 中级黑马 2013-11-10 21:08:22
9#
轩辕迪卡 发表于 2013-11-10 14:34
你好,首先说你对局部变量和全局变量掌握的不好,我认为是这样,其实你完全可以把String换成int类型,试一 ...

补充一下,c里面所谓的指针传递也只是地址值的传递,通常在实际使用中会用引用传递来代替指针传递这种用法,省内存且安全.这里引用的概念跟java就完全不一样了,我想你应该知道,总结来说好像并没有太大冲突,揪这些所谓的字眼貌似意义没不是很大~ 本身计算机语言的概念用中文翻译过来解释就是有些山寨的 呵呵
回复 使用道具 举报
Lucking 发表于 2013-11-10 21:08
补充一下,c里面所谓的指针传递也只是地址值的传递,通常在实际使用中会用引用传递来代替指针传递这种用法, ...

没错,确实没错,我的意思是只要告诉楼主,String要按照基本数据类型,把它当做int,float就好,其它JVM里面怎么调度根本不关开发人员的的事。
回复 使用道具 举报
Lucking 发表于 2013-11-10 20:58
java的引用实质上就是c/c++的指针概念,但是java的参数传递都是通过实参的拷贝来传递的,所以java中只有所 ...

其实都没什么大不了,个人的表达方式不同呗,本质都是一样的,其实我的意思是说只要把String当成int,float的基本数据类型理解就没错,至于JVM的调度,我们不用管。过多的深入理解反而容易出错
回复 使用道具 举报
轩辕迪卡 发表于 2013-11-11 08:38
其实都没什么大不了,个人的表达方式不同呗,本质都是一样的,其实我的意思是说只要把String当成int,flo ...

个人觉得作为应用开发工程师,对细节抠太细未必是什么好事,能实实在在做出项目来才是高手,不过一般c/c++出身的都有这毛病,呵呵 请见谅~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马