这是Java中一个很经典的问题,在stack-overflow上有很多类似的问题,然而很多回答都是错的或者回答不完整;如果你不深入思考的话,会认为这个问题很简单,但是当你深入下去,会发现这个问题很容易让人产生困惑。

一段有趣且让人困惑的代码

package simplejava;public class Q14 {public static void change(String x) {x = "cd";}public static void main(String[] args) {String x = new String("ab");change(x);System.out.println(x);}}

结果打印:

ab

C++版本如下:

void change(string &x) {x = "cd";
}

int main(){string x = "ab";change(x);cout << x << endl;
}

打印结果:

cd

常见有误的理解

x变量存储了堆中“ab”对象的引用,当x作为一个参数传入到change()方法内部时,仍然指向堆中的“ab”对象,如下所示:

因为Java是按值传递的,x的值是“ab”对象的引用,当方法change()被调用时,创建了一个新的对象“cd”,然后x指向“cd”对象,如下图所示:

这看起来像是一个完美的解释,他们很清楚Java总是按值传递的。但是,问题到底出在哪里呢?

这段代码到底究竟在做什么

上面的解释有若干处错误,为了更加容易的理解该问题,我们还是先理清下整个过程。

当字符串对象“ab”被创建的时候,Java分配了对应大小的内存空间,然后对象被赋值给变量x,事实上是x变量存储的是对象的引用,这个引用是“ab”对象在内存中的地址;

x变量包含了对象的引用,x并不是“ab”对象,而是一个存储了“ab”对象引用(内存地址)的变量。

Java是按值传递的,当x被传入change()方法的时候,事实上传入的是一个x变量的拷贝。然后在方法change()内部创建了另一个对象“cd”,它有一个不同的引用。真正改变的是这个x变量的拷贝,其值变成了“cd”对象的引用,而不是原始的x变量被改变;

注:感觉说得有点混乱,我的理解,先说这个参数x,其相当于一个局部变量,当使用该参数的时候,将会分配一个新的存储位置,将实参拷贝到该位置,并将该拷贝值传递给该方法;

在change()方法内部,执行x = "cd"的时候,这里的x实际上是main方法的x变量的一个拷贝,一开始其存放的是“ab对象”的引用,执行完这段代码后,其值变成“cd”对象的引用,而main方法的x变量并没有改变,存放的仍然是“ab”对象的引用。

另一错误解释

这个问题的原因跟字符串的不变形没任何关系,即使将String替换成StringBuilder对象,结果仍然不变,关键点是变量存储的是对象的引用,而不是对象本身;

解决这个问题的方法

如果真的想改变这个对象的值,

首先这个对象是要可改变的,例如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");
}

译文链接:http://www.programcreek.com/2013/09/string-is-passed-by-reference-in-java/

转载于:https://www.cnblogs.com/chenpi/p/5494980.html

字符串是通过“引用”传递的相关推荐

  1. 面试官刁难:Java字符串可以引用传递吗?

    老读者都知道了,六年前,我从苏州回到洛阳,抱着一幅"海归"的心态,投了不少简历,也"约谈"了不少面试官,但仅有两三个令我感到满意.其中有一位叫老马,至今还活在我 ...

  2. C#中的引用传递、值传递

    一.传递参数 既可以通过值也可以通过引用传递参数.通过引用传递参数允许函数成员(方法.属性.索引器.运算符和构造函数)更改参数的值,并保持该更改. 二.传递值类型参数 值类型变量直接包含其数据,这与引 ...

  3. 传递字符串_一道经典面试题:字符串在Java中如何通过“引用”传递

    这是Java的一个经典问题. stackoverflow上也有很多类似的问题,有很多不正确/不完整的答案. 如果你想的不多,问题很简单. 但如果你多想想,可能会很困惑. 一.一个有趣且令人困惑的代码片 ...

  4. Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递?

    来自:沉默王二 在逛 Stack Overflow 的时候,发现了一些访问量像阿尔卑斯山一样高的问题,比如说这个:Java 到底是值传递还是引用传递?访问量足足有 188万+,这不得了啊!说明有很多很 ...

  5. java 值传递 和 引用传递

    参考:(http://www.cnblogs.com/woshimrf/p/5263018.html) 参考:(http://www.cnblogs.com/binyue/p/3862276.html ...

  6. Python中值传递和引用传递区别

    原文:http://blog.csdn.net/xuqiaobo/article/details/72236539 举例,函数参数如果是dic,都不需要返回值,原值就被改变了 def aa(dic): ...

  7. javascript之值传递与引用传递

    javascript之值传递与引用传递 在分析这个问题之前,我们需了解什么是按值传递(call by value),什么是按引用传递(call by reference).在计算机科学里,这个部分叫求 ...

  8. java的引用传递_Java的值传递和引用传递

    首先来看一段代码: User类: 1 public classUser {2 privateString name;3 4 publicString getName() {5 returnname;6 ...

  9. Java主方法引用传递_java方法中的参数传递是值传递还是引用传递(转)

    1.当参数变量为基本数据类型或者字符串时: ... ... //定义了一个改变参数值的函数 public static void changeValue(int x) { x = x *2; } .. ...

  10. Python:值传递,引用传递?不存在的,是赋值传递

    Python的变量及其赋值 c/c++/c#/java 里面都有值传递,引用传递的概念,在Python中是如何的? 例 a = 1 b = a print(id(a),id(b)) #14072334 ...

最新文章

  1. 刚刚,百度宣布王海峰升任CTO
  2. Spring Boot 最流行的 16 条实践解读,值得收藏!
  3. 谁是李党生?带领中国本土期刊登上国际C位,施一公说他眼光很毒辣
  4. “天猫精灵”如何为你写诗?人机共创的秘密在这儿
  5. 《响应式Web设计性能优化》一2.1 性能度量基础
  6. java web 有哪些标签库_java web中jsp常用标签
  7. 2023. 连接后等于目标字符串的字符串对
  8. 201671010119 2016-2017-2《Java程序设计》第十四周学习心得
  9. Python项目:用微信自动给女朋友每天一句英语问候
  10. stm32时钟配置总结
  11. python表白代码-python告白代码,只属于程序员的浪漫
  12. cad隐藏图层命令快捷键_CAD各种插件大全汇总,1G多绘图神器+快捷键命令大全,无套路分享...
  13. 直流电机PID控制源码c语言,51单片机PID+PWM直流电机转速闭环控制源码(12864液晶显示)...
  14. 如何修改背景色?证件照背景颜色怎样换成白色?
  15. 我想把生活折腾成自己想要的样子
  16. LightOJ-1090-数论
  17. 大吉大利,今晚吃鸡——跑毒篇
  18. Android studio中的警告Hardcoded text
  19. php5.6解密软件,php解密:php5.4 zend解密核心代码分享
  20. Ada 程序设计语言(The Ada Programming Language)[第一集]

热门文章

  1. matlab没有曲线,有个程序,运行后只有坐标没有曲线,是怎么回事呢 望大神们解答...
  2. php检测http状态码,分享一段php判断url http状态码的代码
  3. Chrome插件GitZip(下载github项目中的部分文件)
  4. php redis返回值,PHP 中redis常用方法
  5. timimg学习数据删了_如何评价Timing这个督促人学习的软件?
  6. 智能翻译android,离线翻译SDK,让智能小设备如虎添翼
  7. huffman编码的程序流程图_基于哈夫曼编码的压缩解压程序(C 语言)
  8. 深度学习群体行为识别python包_入门Python深度学习,学会这个方法事半功倍
  9. (原創) 這學期C++完美的Ending (C/C++) (日記)
  10. c数据库读写分离和负载均衡策略