zoukankan      html  css  js  c++  java
  • 一道笔试题来理顺Java中的值传递和引用传递

    题目如下:

    private static void change(StringBuffer str11, StringBuffer str12) {

    str12 = str11;
    str11 = new StringBuffer("new world");
    str12.append("new world");
    }

    public static void main(String[] args) {
    StringBuffer str1 = new StringBuffer("good ");
    StringBuffer str2 = new StringBuffer("bad ");
    change(str1, str2);
    System.out.println(str1.toString());
    System.out.println(str2.toString());
    }
    
    
    就是这么一个很简单的题目,大家应该知道答案吧? 答案是:

    good new world 
    bad

    下面就来复盘一下为何是这两个答案,下面会做详细的图文分析。 
    要搞明白这个问题,那么就需要明白Java中的值传递和引用传递了。

    Java对象参数传递虽然传递的是地址(引用),但仍然是值调用。是时候需要给引用调用和值调用一个准确的定义了。

    • 值调用(call by value): 在参数传递过程中,形参和实参占用了两个完全不同的内存空间。形参所存储的内容是实参存储内容的一份拷贝。实际上,Java对象的传递就符合这个定义,只不过形参和实参所储存的内容并不是常规意义上的变量值,而是变量的地址。咳,回过头想想:变量的地址不也是一种值吗!

    • 引用调用(call by reference) : 在参数传递的过程中,形参和实参完全是同一块内存空间,两者不分彼此。 实际上,形参名和实参名只是编程中的不同符号,在程序运行过程中,内存中存储的空间才是最重要的。不同的变量名并不能说明占用的内存存储空间不同。

    那么接下来就画图分析文章开头抛出的问题: 
    这里再把代码贴一遍,大家可以对比着代码和图一起看。

    private static void change(StringBuffer str11, StringBuffer str12) {

    str12 = str11;//2
    str11 = new StringBuffer("new world");//3
    str12.append("new world");//4
    }//5

    public static void main(String[] args) {
    StringBuffer str1 = new StringBuffer("good ");
    StringBuffer str2 = new StringBuffer("bad ");
    change(str1, str2);//1
    System.out.println(str1.toString());
    System.out.println(str2.toString());
    }
    
    
    • 执行到第一步的图: 
      test1

    • 执行到第二步的图,这里chage方法中的形参str11,str22是实参str1,str2的地址拷贝。 
      test2

    • 这里str11和str22是实参str1,str2的地址拷贝,接着执行第三步的图: 
      test3

    • 上图中str12地址指向了“good”,接着看第四步图: 
      test3

    • 上图中str11的地址指向了堆中新的对象"new world",接着看第五步的图: 
      test3

    这里图算是画完了,确实不太擅长画图,大家就先勉强看吧。 
    这里有一个很重要的点就是StringBuffer是可变的,具体解释大家可以搜索下。

    因为这里str12.append("new world")直接修改了good的值。所以main函数中打印的会是:good new world。

    到这里就算讲完了,一个很简单的例子,这里算是对之前一道笔试题的复盘,有不对的地方欢迎大家指正。

     
     
     
     
  • 相关阅读:
    8.C++-类的关键字
    BFS-九宫格重排(详解)
    7.C++类与封装的概念
    4.数码相框-freetype多行显示,居中显示
    3.数码相框-通过freetype库实现矢量显示
    Linux-iconv命令、并批处理将所有GBK文件转换为UTF8(18)
    2.数码相框-编码(ASCII/GB2312/Unicode)介绍,并使LCD显示汉字字符(2)
    1.数码相框-相框框架分析(1)
    Kotlin 之操作符重载
    Andorid-解决View重复点击的思路
  • 原文地址:https://www.cnblogs.com/du-0210/p/9288995.html
Copyright © 2011-2022 走看看