string java 引用_五、String在Java中是传“引用”

这个是Java的经典问题。许多类似的问题在stackoverflow被提问,有很多不正确或不完备的答案。如果不想太多你会认为这个问题比较简单。( The question is simple if you don't think too much.)如果你想的多的话,它会非常让你困扰。

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”如下图:

3af43a6a403ad0ee7a317b64dba2d951.png

因为Jva是传值的,x的是“ab”的引用。当方法change()被调用时,

它创建个新的“cd”对象,x现在指向“cd”如下:

9d1d5fa7a4603ac0a23a2b1d4c2967cd.png

这看起来像是非常很里的解释,它们清晰的描述了Java中按值传递。

但是这里有什么错吗?

3、代码实际上怎么做的?

上面解释有几个错误。为了方便理解,简单跟踪整个过程是个好主意。

当字符串“ab“被创建时,Java分配了大量的内存去存在这个字符串对象。因此,这个对象被赋值给变量x,这个变量实际被赋值给这个对象的引用。引用是一个存在这个对象的内存地址。

变量x存储一个字符串对象的引用。但是x不是自己不是引用。它是一个存储引用的变量(内存地址)。

Java只有传值。当x被传递给change()方法时,一份x值(一个引用)的拷贝被传递。当change()方法创建另外一个“cd“对象时候,它有个不同的引用。变量x改变了它的引用(指向”cd“),而不是引用自己。

下图显示了实际发生的。

5f093bd6c027548374b6d5775e93a4e5.png

4、错误的解释

第一个代码片段的问题与字符串的不可变性无关。即使用StringBuilder替代String,结果仍然相同。关键是变量存储了引用,但是不是引用本身。

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");

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值