一道笔试题来理顺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中只有值传递,没有引用传递. 那么关于对象的传 ...
随机推荐
- Myeclipse和idea对比
新入的公司要用myeclipse,没办法,只能跟着队伍走.(myeclipse以下简写为me) 1.myeclipse的快捷键并不能设置鼠标滚轮之类的,之前在idea上配置滚轮下滚展开package, ...
- JSON.stringify()方法是将一个javascript值(对象或者数组)转换成为一个JSON字符串;JSON.parse()解析JSON字符串,构造由字符串描述的javascript值或对象
JSON.stringify()方法是将一个javascript值(对象或者数组)转换成为一个JSON字符串:JSON.parse()解析JSON字符串,构造由字符串描述的javascript值或对象
- 2015-10-29 ado.net 1
ADO.NET 一.什么是ado.net ADO.NET是一组允许.NET ...
- kafka 常用参数
通常的讲:kafka 的参数分为 Broker Configs 和 Topic-Level Configs,以 min.insync.replicas 为例,可以在 broker 和 topic 级别 ...
- 基于Protostuff实现的Netty编解码器
在设计netty的编解码器过程中,有许多组件可以选择,这里由于咱对Protostuff比较熟悉,所以就用这个组件了.由于数据要在网络上传输,所以在发送方需要将类对象转换成二进制,接收方接收到数据后,需 ...
- pip更新
python -m ** install -U **
- K2百家讲坛 | 越秀地产:K2为房企数字化转型带来更多可能
随着数字化经济时代的到来,房地产行业逐渐形成了新的竞争和市场格局,房企要在此背景下实现稳步发展,需要由原本的粗放式管理逐渐向集团性管理.精细化管控转变,这对房企的经营发展战略和业务管理方式都提出了不小 ...
- Mac上安装Docker
安装这个东东有两种方法:在线安装和手动安装 在线安装: 打开终端,直接输入brew cask install docker之后回车,执行的过程中会要求输入password(就是你电脑的登录密码),输入 ...
- window.opener和window.open
window.open (URL,name,specs,replace)方法用于打开一个新的浏览器窗口或查找一个已命名的窗口. URL:可选.打开指定的页面的URL.如果没有指定URL,打开一个新的空 ...
- 记初学python的一些心得
人生苦短,我用python! 其实我自学python也很长一段时间了,但总是去更换学习资料,搞的现在学的不是很好,因为没更换次资料都要从头开始学起,那么分享下我的学习战况吧,不是很好,还将就的能看. ...