Simple Java—Strings and Arrays(一)String是引用传值吗?
来源:互联网 发布:淘宝与京东 编辑:程序博客网 时间:2024/06/06 18:08
Translate from String is passed by “reference” in Java
在Java中有一个经典的问题。许多相似的疑问在stackoverflow上被提出,也有许多错误或者不完全的解释被回答。如果你不思考太多,这个问题其实很简单。但是如果你深入的去思考它,你又会变得十分困惑。
1. 一段有趣而困惑的程序
public static void main(String[] args) { String x = new String("ab"); change(x); System.out.println(x);}public static void change(String x) { x = "cd";}
输出结果为“ab”
在C++中,程序如下:
void change(string &x) { x = "cd";}int main(){ string x = "ab"; change(x); cout << x << endl;}
输出结果为”cd”
2. 疑惑
x存储着指向堆中字符串”ab”的引用。当x传给方法change()的 形参时,它仍然指向堆中的“ab”:
因为java是按值传递的,x的值是指向”ab”的引用。当方法change()执行时,创建了一个新的”cd”对象,所以现在x是指向”cd”的:
这看上去是一个非常合理的解释,非常清楚的是,Java总是按值传递的,所以,到底是哪里错了呢?
3. 这段代码到底做了什么?
上面的解释有几个错误点,为了更简单的明白它,最好简短的走一下程序的整个过程。
当字符串”ab”被创建时,Java分配了一段内存来存储这个字符串对象。然后,这个字符串对象被分配给了变量x,变量x实际上存储的是对象的“引用”,即“ab”在内存中存储的地址。
变量x包含了对字符串的引用,但x不是这个引用的本身!它是一个存储了引用(内存地址)的变量
Java只按值传递,当x传递给方法change()中的形参时,x中的值被复制了过去。当方法change()创建一个新的字符串对象”cd”时,形参有了不同的指向。注意,是形参改变了它的指向(“cd”),不是引用本身改变。
(PS:这段比较绕,意思其实就是形参本身的值被换成了cd的地址,不存在指向ab的”引用”又指向了cd)
接下来的图说明了整个过程:
4. 错误的理解
第一段代码引出的问题和“Java不变性”没有一点关系,就算String被换成了StringBuilder,结果也不会变。这个问题的关键在于了解:变量存储这引用,但变量不是引用本身!
5.问题的解决办法
如果我们真的想要改变这个对象的值,首先,这个对象应该可以被改变,例如StringBuilder。第二,我们需要确定没有新的对象被创建并分配给变量。因为Java只按值传递
public static void main(String[] args) { StringBuilder x = new StringBuilder("ab"); change(x); System.out.println(x);}public static void change(StringBuilder x) { x.delete(0, 2).append("cd");}
我的总结:
- 最重要的一点:Java只按值传递的。
- 之所以String这个对象的值没有改变,是因为形参被赋值后直接修改了里面存储的内存地址,而不是原内存地址中内容
- 第一段代码,C++和Java的不同,按我个人理解,是因为C++是按照引用传递的。需要注意的是,引用传递和 指针传递是不同的概念,实际上,指针传递还是按值传递:C++引用传递和值传递
- Simple Java—Strings and Arrays(一)String是引用传值吗?
- Simple Java—Strings and Arrays(三)为什么String被设计成了不可变型
- Simple Java—Strings and Arrays(四)从length和length()开始谈Java
- Simple Java—Strings and Arrays(六)Java中的null值是什么?
- Simple Java—Strings and Arrays(二)substring()在jdk6和jdk7中的不同
- Simple Java—Strings and Arrays(五)如何在java中有效率的检查一个数组中是否有某值?
- 【CareerCup】 Arrays and Strings—Q1.1
- 【CareerCup】 Arrays and Strings—Q1.2
- 【CareerCup】 Arrays and Strings—Q1.3
- 【CareerCup】 Arrays and Strings—Q1.4
- 【CareerCup】 Arrays and Strings—Q1.5
- 【CareerCup】 Arrays and Strings—Q1.6
- 【CareerCup】 Arrays and Strings—Q1.7
- CCI(1)-- Arrays and Strings
- CCI(2)-- Arrays and Strings
- Arrays and Strings----1
- Arrays and Strings----3
- Arrays and Strings----4
- Android-在浏览器启动Activity
- example datasets in sklearn
- NSRange类详解
- 安卓进程通讯之aidl
- HDOJ 1242 Rescue
- Simple Java—Strings and Arrays(一)String是引用传值吗?
- zzulioj--1638--Happy Thanksgiving Day - Say 3Q I(水题)
- ROS naviagtion analysis: costmap_2d--ObstacleLayer
- 自己编写栈和队列的声明和调用
- CodeForces 611C New Year and Domino【预处理】
- Java使用RSA加密解密签名及校验
- [消息传递之七]-KVO练习
- 2016-01-10 FFC
- 【Java】使用Json-lib序列化关联对象的异常解决