Example 1
上面这段代码,最终会输出什么?
答案是 hello
有人就会说为啥,我的java学错了吗?String不是引用类型吗?hello方法改变了变量str堆中的值了啊!
我猜很多同学之前了解到的是 Java中基本数据类型是值传递,引用类型是地址传递。那么这段代码为什么跟预期的不一致呢?我们再来看个例子。
Example 2
有了上面例子的经验,小伙伴们这下也不敢确定了。
那这段代码最终是输出[hello, world]还是[hello, java]呢?
正确答案是[hello, world]!
那同学们又有疑惑了,我这明明用了new关键字,代表把变量strArr指向了新的内容,为什么最终输出跟预想的还是不一样呢?
这里提出一个论点
Java中其实没有引用地址传递,都是值传递,实参作为形参给方法时,其实是复制了一份引用地址副本给方法处理。所以方法中把引用地址副本变为一个新的对象,关我本体屁事。哈哈。
但你以为这就结束了吗?还不止于此,我们再来看个例子
Example 3
这次我们把例子2中的创建数组操作变为赋值操作,那这段代码的输出结果是什么呢?
相信小伙伴们这次命中了你们的知识点了。没错,坚定你们的想法。输出结果就是[hello, java]!
我猜小伙伴们虽然知道结果,但感觉上好像有一点问题。经过上面两个例子的洗礼后,感觉就是哪里不太对。
对,上面不是说了实参作为形参给方法时,其实是复制了一份引用地址副本给方法处理吗?那为什么这个例子会影响到本体呢?
这个问题其实跟小伙伴们原有的认知是一致的,所以就出现引用传递这个说法。你看,我这不是改变了本体的值了吗!完全就像是把本体的引用传递给了方法啊!
其实我们按刚才的论点的说法再来思考下,如果不是引用传递,这是个副本的话,那么这个副本的引用和本地的引用都是指向堆中那同一个数据,所以副本引用改变了堆中数据的值,那本体的值也相应改变了。
结论
- Java中其实没有引用地址传递,都是值传递,实参作为形参给方法时,其实是复制了一份引用地址副本给方法处理
- Java中可以多个引用指向同一份堆数据,这种情况下,会产生类似引用传递的情况




近期评论