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

      

  • 相关阅读:
    火狐flash插件
    centos 安装php ide (eclipse + php 插件)
    编译器的工作过程
    php中调用mysql的存储过程和存储函数
    mysql 高性能
    存储过程/游标/mysql 函数
    php 生成二维码
    frameset,frame应用,常用于后台
    html5 meta头部设置
    CAReplicatorLayer复制Layer和动画, 实现神奇的效果
  • 原文地址:https://www.cnblogs.com/zeng-wei/p/3494336.html
Copyright © 2011-2022 走看看