这是一个经典的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.这段代码到底做了什么?


上面的解释有几处错误。为了更容易理解,我们最好简单的过一下整个流程。

当字符串"cd" 被创建时,java会分配储存字符串所需要的内存量。然后,对象被分配给了变量x,实际上是将对象的引用分配给了变量x。这个引用是对象储存的内存地址。

变量x包含了一个指向字符串对象的引用,x并不是字符串对象本身。它是一个储存了字符串对象'ab'引用的变量。

java是按值传递的。当x被传递给change()方法时,实际上是x的值(一个引用)的一个副本。方法change被调用后,会创建另一个对象"cd",它有着一个不同的引用。方法内的局部变量x的值变成了"cd"的引用。这里改变的是方法内的局部变量的引用值,而不是改不了原先引用的字符串"ab"。

看图:

4.错误的解释:


从第一个代码片段引发的问题与字符串不可变性没有任何关系。即使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");
}

作者:在下贼溜
链接:https://www.jianshu.com/p/df903886b5a9
來源:简书

关注我们"java工会",获取更多java技术干货,等你来撩!

在Java中字符串是通过引用传递的?的更多相关文章

  1. 三张图彻底了解Java中字符串的不变性

    转载: 三张图彻底了解Java中字符串的不变性 定义一个字符串 String s = "abcd"; s中保存了string对象的引用.下面的箭头可以理解为"存储他的引用 ...

  2. java中字符串的非空判断

    问题如下:在java 中 字符串为null 如何判断String str;if(str==null) ??str.equal("null") ?? 答:我觉得应该搞清楚字符串对象和 ...

  3. JAVA中的四种引用以及ReferenceQueue和WeakHashMap的使用示例

    简介: 本文主要介绍JAVA中的四种引用: StrongReference(强引用).SoftReferenc(软引用).WeakReferenc(弱引用).PhantomReference(虚引用) ...

  4. Java中的基本类型和引用类型变量的区别

    Java中的基本类型和引用类型变量的区别   学了一年多,说实话你要我说这些东西我是真说不出来是啥意思     基本类型: 基本类型自然不用说了,它的值就是一个数字,一个字符或一个布尔值. 引用类型: ...

  5. Java中字符串string的数据类型

    Java中字符串string的数据类型 时间:2017-07-03 08:01:47 YuanMxy 原文:https://blog.csdn.net/YuanMxy/article/details/ ...

  6. java中字符串比较==和equals

    1 总体来说java中字符串的比较是==比较引用,equals 比较值的做法.(equals 对于其他引用类型比较的是地址,这是因为object的equals方法比较的是引用),但是不同的声明方法字符 ...

  7. Java中字符串的一些常用操作方法

      package test; public class  maintest {public static void main(String[] args) {String str = "a ...

  8. java中字符串String 转 int(转)

    java中字符串String 转 int String -> int s="12345"; int i; 第一种方法:i=Integer.parseInt(s); 第二种方法 ...

  9. 【转】Java中字符串中子串的查找共有四种方法(indexof())

    原文网址:http://wfly2004.blog.163.com/blog/static/1176427201032692927349/ Java中字符串中子串的查找共有四种方法,如下:1.int ...

随机推荐

  1. WPF Window对象的生命周期

    WPF中所有窗口的基类型都是System.Windows.Window.Window通常用于SDI(SingleDocumentInterface).MDI(MultipleDocumentInter ...

  2. 在myeclipse中换项目的jdk版本,你需要做哪些?

    首先,我们必须把jdk在系统中安装好,环境变量配好,才能进行下一步的操作…… 然后在点击项目,右键选择Properties,找到Java Build Path,拉倒最下面,把原来的jdk版本给remo ...

  3. Require.js 源码分析

    本文将简单介绍下个人对require.js的源码分析,简单分析实现原理 一.require加载资源的流程 require中,根据AMD(Asynchronous Module Definition)的 ...

  4. Laravel 使用Voyager导致多个数据库连接总是返回默认连接?

    问题与分析 最近的项目碰到一个奇怪的问题,在Laravel(5.3)中想建立多个数据库连接连到MySQL的不同数据库(另一个连接名为conn2),执行如下语句得到却发现得到的仍然是默认连接: $con ...

  5. JavaScript中Undefined 和 Null的区别

    Undefined 这个值表示变量不含有值. 可以通过将变量的值设置为 null 来清空变量. 例如: <script> var person; var car="Volvo&q ...

  6. The Internet Communications Engine (Ice) 跨平台异构通讯方案 第一弹-ICE简介

    .net中的通讯方案很多,从.net Remoting,MSMQ,Webservice,WSE,WCF等等,他们都有一个特点,易用,但是都不能跨语种异构,如果你服务端要用java开发,客户端用C#开发 ...

  7. equals()重写

    ** 注意 ** 1.重写equals方法修饰符必须是public,因为是重写的Object的方法. 2.参数类型必须是Object. 3.重写equals方法后最好重写hashCode方法,否则两个 ...

  8. 洛谷P2831 愤怒的小鸟(状压dp)

    题意 题目链接 Sol 这题....我样例没过就A了??..算了,就当是样例卡精度吧.. 直接状压dp一下,\(f[sta]\)表示干掉\(sta\)这个集合里面的鸟的最小操作数 转移的时候判断一下一 ...

  9. Codeforces Round #414 A. Bank Robbery

    A. Bank Robbery time limit per test 2 seconds memory limit per test   256 megabytes   A robber has a ...

  10. 字符数字转换 atoi 与 strtol

    原文:http://www.cnblogs.com/JefferyZhou/archive/2010/07/01/1769555.html 在很多时候我们都很清楚 atoX 系列函数: atoi , ...