zoukankan      html  css  js  c++  java
  • Java中String是“引用”传递

    如题,在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”.

    2. 通常让人迷惑的解释如下

    在java堆中x存储指向“ab”的引用。所以当x作为参数传递给change()方法时,它在内存中仍然指向“ab”,如下:

    string-pass-by-reference

    由于java是值传递,所以此时x仍然指向“ab”。当chang()方法执行时,它在内存中创建了一个新的String对象“cd”,并且现在x指向“cd”,如下:

    string-pass-by-reference 2

    上面的解释看起来非常合理。他们也很清楚java是值传递。但是哪里出错了?

    3. 上面的代码到底如何执行的呢?

    上面的解释有几处错误。跟踪代码执行全过程是一个很好的方法,并且理解起来很容易。

    当“ab”创建后,java分配对象所需内存空间。然后,变量x指向了“ab”,变量实际上是指向对象的引用。这个引用指向对象存储的地址。

    x保存了一个指向String对象的地址。x不是引用本身!它是保存一个内存地址。

    在Java中只有值传递。当x通过参数传递给change()方法后,x被拷贝了一份。change()创建了另一个对象“cd”,并且x指向了不同的地址空间。实际上是x改变它的引用(指向“cd”),不是x本身。

    下图展示了x在内存的变化

    string-pass-by-reference 3

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

      

  • 相关阅读:
    [Linux]yum开启rpm包缓存
    [Linux]centOS7-1-1503-x86_64下安装VM-TOOLS
    [Linux]centOS7下RPM安装Perl
    vue 之 pageage.json 和 webpack.config.js
    node 之 apache
    node 之 express
    node 之 基础知识
    npm nvm nrm的关系
    echarts 学习笔记
    git 操作学习
  • 原文地址:https://www.cnblogs.com/zeng-wei/p/3494336.html
Copyright © 2011-2022 走看看