题目如下:

  1. private static void change(StringBuffer str11, StringBuffer str12) {
  2.  
  3. str12 = str11;
    str11 = new StringBuffer("new world");
    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);
    System.out.println(str1.toString());
    System.out.println(str2.toString());
    }
  1.  
就是这么一个很简单的题目,大家应该知道答案吧? 答案是:

good new world 
bad

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

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

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

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

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

  1. private static void change(StringBuffer str11, StringBuffer str12) {
  2.  
  3. str12 = str11;//2
    str11 = new StringBuffer("new world");//3
    str12.append("new world");//4
    }//5
  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());
    }
  1.  
  • 执行到第一步的图: 

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

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

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

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

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

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

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

 
 
 
 

一道笔试题来理顺Java中的值传递和引用传递的更多相关文章

  1. 【笔试题】在 Java 中,如何跳出当前的多重嵌套循环?

    笔试题 在 Java 中,如何跳出当前的多重嵌套循环? public class Demo { public static void main(String[] args) { System.out. ...

  2. 通过一道笔试题浅谈javascript中的promise对象

    因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...

  3. Does Java pass by reference or pass by value?(Java是值传递还是引用传递) - 总结

    这个话题一直是Java程序员的一个热议话题,争论不断,但是不论是你百度搜也好还是去看官方的文档中所标明的也好,得到的都只有一个结论:Java只有值传递. 在这里就不贴代码细致解释了,让我们来看看一些论 ...

  4. Java中有关构造函数的一道笔试题解析

    Java中有关构造函数的一道笔试题解析 1.详细题目例如以下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与c ...

  5. Java 面试/笔试题神整理 [Java web and android]

    Java 面试/笔试题神整理 一.Java web 相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并 ...

  6. 一道笔试题和UML思想 ~

    一句软件工程界的名言,让我想起了一个和一道笔试题有关的故事.希望更多的人了解 UML 背后的思想比他的语法更重要,是笔者写作本文的一点小愿望. 一.从一句软件工程名言说起 对很多事情的处理上,东西方都 ...

  7. Java 中的值传递和参数传递

    Java中没有指针,所以也没有引用传递了,仅仅有值传递不过可以通过对象的方式来实现引用传递 类似java没有多继承 但可以用多次implements 接口实现多继承的功能 值传递:方法调用时,实际参数 ...

  8. java中方法的参数传递机制(值传递还是引用传递)

    看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参 ...

  9. 为什么说Java中只有值传递?

    一.为什么说Java中只有值传递? 对于java中的参数传递方式中是否有引用传递这个话题,很多的人都认为Java中有引用传递,但是我个人的看法是,Java中只有值传递,没有引用传递. 那么关于对象的传 ...

随机推荐

  1. sass学习小记

    错误 在sass命令行编译中遇到了一个错误: error E:/前端2/css揭秘/CSS-study/css揭秘/css揭秘.scss (Line 29: Invalid GBK character ...

  2. Kubernetes 入门之Kubernetes 的基本概念和术语

    Kubernetes是什么?    他是一个全新的基于容器技术分布式架构领先方案:    他也是一个开放的开发平台:    他也是一个完备的分布式系统支撑平台:   Kubernetes的基本慨念和术 ...

  3. nginx反向代理后应用程序如何获取客户端真实IP

    每个location中增加配置: proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_se ...

  4. centos更换网易的源

    刚安装的centos系统下载软件可能很慢,就可以试一下更换为国内比较知名的源试试.现在知道的网易和中科大源很不错.那么怎么更换呢 1. cd /etc/yum.repos.d/           c ...

  5. Android Studio之SVN打分支、切换分支及合并分支

    1.打分支: 右击项目--Subversion--Branch or Tag 点击OK,分支就创建成功了,接下来我们切换到分支v2 2.切换分支: 右击项目--Subversion--Update D ...

  6. Python_Mix*生成器,生成器函数,推导式,生成器表达式

    生成器: 生成器的本质就是迭代器 生成器一般由生成器函数或者生成器表达式来创建,其实就是手写的迭代器 def func(): print('abc') yield 222 #由于函数中有了yield ...

  7. 构建Java开发环境(JDK)

    在我们学习Java前我们需要构建相对应的开发环境.JDK(Java Development Kit)是Java开发的必备条件. Java 的JDK是Sun公司的产品,但由于Sun公司被Oracle公司 ...

  8. C#中d的??和?

    在C#中??和?分别是什么意思?   1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; 是正确的,int i=nu ...

  9. 【webpack学习笔记】a02-管理资源

    在webpack 中,各种资源要引入,要用到module配置,比如css/图片/字体等等. 例如: module.exports = { entry: './src/app.js', //这是入口文件 ...

  10. Android : 高通平台Camera调试之SetpropKey/camxoverridesettings.txt

    高通相关网址:Createpoint: https://createpoint.qti.qualcomm.com(可下载文档,Release Note等)Chipcode: https://chipc ...