一道笔试题来理顺Java中的值传递和引用传递

时间:2022-08-25 12:31:12
 

题目如下:

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

  • 执行到第一步的图: 
    一道笔试题来理顺Java中的值传递和引用传递

  • 执行到第二步的图,这里chage方法中的形参str11,str22是实参str1,str2的地址拷贝。 
    一道笔试题来理顺Java中的值传递和引用传递

  • 这里str11和str22是实参str1,str2的地址拷贝,接着执行第三步的图: 
    一道笔试题来理顺Java中的值传递和引用传递

  • 上图中str12地址指向了“good”,接着看第四步图: 
    一道笔试题来理顺Java中的值传递和引用传递

  • 上图中str11的地址指向了堆中新的对象"new world",接着看第五步的图: 
    一道笔试题来理顺Java中的值传递和引用传递

这里图算是画完了,确实不太擅长画图,大家就先勉强看吧。 
这里有一个很重要的点就是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. 【BZOJ1415】 [Noi2005]聪聪和可可 概率与期望

    其实题不难,不知提交了几次...不能代码MD...注意一些基本问题...SB概率题 #include <iostream> #include <cstdio> #include ...

  2. 【hdu2196】Computer

    hdu 2196 computer 题意 给你一棵树,边有权值. 对于每一个点,求其与其距离最远的点的距离. 分析 思路1:树的直径 利用直径的性质进行求解,网上资料很多,这里不赘述. #includ ...

  3. php Late Static Bindings延迟静态绑定

    官网说道: As of PHP 5.3.0, PHP implements a feature called late static bindings which can be used to ref ...

  4. sklearn两种保存模型的方式

    作者:卢嘉颖 链接:https://www.zhihu.com/question/27187105/answer/97334347 来源:知乎 著作权归作者所有,转载请联系作者获得授权. 1. pic ...

  5. Nctf&lowbar;web&lowbar;wp

    1.签到题     右键源代码即可2.md5 collision    这个考点是php"=="的弱相等,为何会出现弱加密呢,是因为在比较==两边的时候,会将字符串类型转化为相同, ...

  6. 201771010126 王燕《面向对象程序设计(java)》第八周学习总结

    实验六 接口的定义与使用 实验时间 2018-10-18 1.实验目的与要求 (1) 掌握接口定义方法 JAVA中通过interface关键字定义接口: 接口中只能定义public static fi ...

  7. TCP 选项RST

    1.RST介绍 RST表示reset复位,用于异常情况下关闭连接. 发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓冲区中的包. 而接收端收到RST包后,也不必发送ACK包来确认. 2. ...

  8. Python巧用正则表达式,完成接口参数替换

    最近给Python11期的小朋友们上课,遇到了一个参数替换的问题,首先描述下场景: 需要参数化的数据如下所示: 这个时候如果利用单纯的if判断和字符串的find和replace方法,做起来是非常不明智 ...

  9. 支持辉光效果的Label

    支持辉光效果的Label 效果 源码 https://github.com/YouXianMing/UI-Component-Collection 中的 FBGlowLabel // // FBGlo ...

  10. 如何搭建hibernate框架

    我写这篇博客,主要是想让大家能够快速上手hibernate,本人建议学习框架,应该一个框架一个框架学习,别一上手就三大框架整合,学习之类的.这里只是单独搭建hibernate框架,让大家 能够更好的上 ...