一道笔试题来理顺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());
}
执行到第一步的图:
执行到第二步的图,这里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中的值传递和引用传递的更多相关文章
- 【笔试题】在 Java 中,如何跳出当前的多重嵌套循环?
笔试题 在 Java 中,如何跳出当前的多重嵌套循环? public class Demo { public static void main(String[] args) { System.out. ...
- 通过一道笔试题浅谈javascript中的promise对象
因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...
- Does Java pass by reference or pass by value?(Java是值传递还是引用传递) - 总结
这个话题一直是Java程序员的一个热议话题,争论不断,但是不论是你百度搜也好还是去看官方的文档中所标明的也好,得到的都只有一个结论:Java只有值传递. 在这里就不贴代码细致解释了,让我们来看看一些论 ...
- Java中有关构造函数的一道笔试题解析
Java中有关构造函数的一道笔试题解析 1.详细题目例如以下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与c ...
- Java 面试/笔试题神整理 [Java web and android]
Java 面试/笔试题神整理 一.Java web 相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并 ...
- 一道笔试题和UML思想 ~
一句软件工程界的名言,让我想起了一个和一道笔试题有关的故事.希望更多的人了解 UML 背后的思想比他的语法更重要,是笔者写作本文的一点小愿望. 一.从一句软件工程名言说起 对很多事情的处理上,东西方都 ...
- Java 中的值传递和参数传递
Java中没有指针,所以也没有引用传递了,仅仅有值传递不过可以通过对象的方式来实现引用传递 类似java没有多继承 但可以用多次implements 接口实现多继承的功能 值传递:方法调用时,实际参数 ...
- java中方法的参数传递机制(值传递还是引用传递)
看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参 ...
- 为什么说Java中只有值传递?
一.为什么说Java中只有值传递? 对于java中的参数传递方式中是否有引用传递这个话题,很多的人都认为Java中有引用传递,但是我个人的看法是,Java中只有值传递,没有引用传递. 那么关于对象的传 ...
随机推荐
- 搭建Java开发环境及相关工具
本文主要记录下在window环境下,搭建Java开发环境,及需要安装的工具软件说明,旨在方便快速完成这些正真开始开发前的准备工作. 1.JDK安装及环境配置 此处安装JDK1.8的版本,官方下载地址: ...
- 利用python解析地址经纬度和利用经纬度定位地址
解析地址经纬度 from geopy.geocoders import Nominatim try: geolocator = Nominatim() location = geolocator.ge ...
- Python3+slowloris安装使用教程
一.说明 今天提到slowloris,这东西看着很眼熟,应该是以前局方打算用来刷竞赛积分的工具.我总觉得DoS没什么意思,但记不得怎么用了所以还是研究一下. 二.安装 slowloris就是一个pyt ...
- Win10系列:C#应用控件进阶8
LineGeometry LineGeometry控件通过指定直线的起点和终点来定义线.LineGeometry对象无法进行自我绘制,因此同样需要使用 Path元素来辅助呈现.LineGeometry ...
- Java垃圾回收算法和内存分配策略
垃圾回收算法和内存分配策略 Java垃圾回收 垃圾收集,也就是GC并不是Java的伴生物,而对于GC的所需要完成任务主要就是: 1.哪些内存是需要回收的? 2.何时去回收这些内存? 3.以何种方式去回 ...
- 用VS2017编写C语言的Hello World
1.新建项目 2.选择新建空项目 3.在源文件处右键单击,选择添加-新建项 4.选择“c++文件”,将名称后缀改成.c即可用C语言编写程序 5.编写代码: #include <stdio.h&g ...
- win10 adb(Android Debug Bridge)导出日志
百度了一下 各种设置环境变量.放到system32文件夹(64位系♂统放到C:\Windows\SysWOW64)等 公司电脑win10系统 方便多了 把环境变量设置啥的全删了 adb下载地址:htt ...
- hosts文件被修改后的惨案
在公司MAC电脑上/etc/hosts中尝试反向解析一个ip到localhost, 即:xxx.xxx.xxx.xxx localhost 然后发现tomcat起不来;
- H5横向滚动提示
<marquee>啦啦啦,Hello World</marquee>
- ubuntu google chrome 全屏显示命令
全屏模式:kiosk默认全屏打开一个网页呢,只需要在快捷方式中加上 --kiosk [url] 就可以了.终端命令行打开: google-chrome --kiosk www.baidu.com 参考 ...