转自:微点阅读(www.weidianyuedu.com)微点阅读 - 范文大全 - 免费学习知识的网站

在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式: 
A. 是按值传递的? 
B. 按引用传递的? 
C. 部分按值部分按引用? 
此处暂不宣布正确答案,我们通过一个简单的例子让大家自己找答案: 
1. 先定义一个类型Value

Java代码

  1. public static class Value {
  2. private String value = "value";
  3. public String getValue() { return value; }
  4. public void setValue(String value) { this.value = value; }
  5. }

2. 写两个函数newValue和modifyValue:newValue会将入参指向一个新的对象,modifyValue会调用入参的setValue方法修改对象的value值。

Java代码

  1. public static void newValue(Value value) {
  2. value = new Value();
  3. value.setValue("new value");
  4. System.out.println("In newValue, HashCode = " + value.hashCode() + ", value = " + value.getValue());
  5. }
  6. public static void modifyValue(Value value) {
  7. value.setValue("new value");
  8. System.out.println("In modifyValue, HashCode = " + value.hashCode() + ", value = " + value.getValue());
  9. }

3. 简单的测试代码

Java代码

  1. public static void main(String[] args) {
  2. Value value1 = new Value();
  3. System.out.println("Before modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue());
  4. // 将value1指向新的Value对象
  5. newValue(value1);
  6. System.out.println("After modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue() + "\n");
  7. Value value2 = new Value();
  8. System.out.println("Before modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue());
  9. // 使用object的set方法,修改对象的内部值
  10. modifyValue(value2);
  11. System.out.println("After modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue());
  12. }

4. 执行结果日志:

Java代码

  1. Before modify, HashCode = 12677476, value = value
  2. In newValue, HashCode = 33263331, value = new value
  3. After modify, HashCode = 12677476, value = value
  4. Before modify, HashCode = 6413875, value = value
  5. In modifyValue, HashCode = 6413875, value = new value
  6. After modify, HashCode = 6413875, value = new value

5. 结果分析: 
上述代码这是非常常见的一种编程模式:在外围定义|保存|获取一个值或对象,将这个对象作为参数传入一个方法,在方法中修改对象的属性、行为。但两个方法newValue和modifyValue的修改方式不一样,在方法调用之后,该对象在外围看来也有很大的差别!如何理解这种差异呢?先温故一下按值传递、按引用传递的概念: 
* 按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。 
* 按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,参数的原始值(函数块之外的调用代码中)也随之改变。 
正确的答案:A——Java函数是按值传递参数的! 
分析一下日志: 
* 第一段日志输出,value1参数在newValue方法内部被改为指向新对象,并输出了新对象的hashCode和value值,但跳出newValue方法域之后,在main方法中的value1没有发生任何变化,这符合按值传递的定义和特点;如果是按引用传递,value1在调用newValue(Value value)方法之后,应该是发生变化的。 
* 第二段日志输出,value2在modifyValue方法内部进行了setValue操作,hashCode不变而value被修改,离开modifyValue方法域之后,在main方法中value2确实发生了变更。使用过C++的人容易将这种现象理解为:按引用传递函数参数!因为这跟C++中的按引用传递像极了!但这里恰恰是最容易陷入误区的地方! 
两段日志的不同现象背后所隐藏的是原理是:Java语言是按值传递参数,按引用传递对象的;Java中所操作的对象其实都是操作对象的引用,object本身保存在“堆”中,而对象的“引用“保存在寄存器或“栈”中。 
伪代码描述一下newValue方法和modifyValue方法的不同之处:

Java代码

  1. newValue{
  2. Value_ref2 = value_ref1;    // 按值传入引用value_ref1,得到value_ref1的副本
  3. value_obj2 = new Value();   // value_obj2被创建、初始化在“堆“中
  4. value_ref2 -> value_obj2;    // value_ref2 指向value_obj2
  5. value_ref2 ->value_obj2.setValue(“xxx”); // value_obj2 的value被修改
  6. printValueObj2();           // 此处打印的是obj2的值
  7. }
  8. modifyValue{
  9. Value_ref2 = value_ref1;    // 按值传入引用value_ref1,得到value_ref1的副本
  10. value_ref2 ->value_obj1.setValue(“xxx”); // value_obj1 的value被修改
  11. printValueObj1();           // 此处打印的是obj1的值
  12. }

够清楚了吧!value1_ref1在作为参数传入函数的时候,首先被复制了一份副本value1_ref2供函数域使用,此时这两个ref都是指向同一个value_obj; newObject函数中的代码[ value = new Value(); ] 其实是将value1_ref1指向了一个新的对象value_obj2;在这之后的set操作都是对新对象的操作;modifyValue函数是通过set方法直接操作value_obj1,这是跟newValue函数的不同之处。

Java函数参数传递方式相关推荐

  1. 天真,居然还有人认为java的参数传递方式是引用传递

    代码写的越急,程序跑得越慢.-- Roy Carlson 时间过得真快,2020已经过去了一半,但是疫情好像还没有真正的消灭,人们出行还是得带着口罩,天气越来越热,受罪啊. 言归正传,都2020年了, ...

  2. 3种函数参数传递方式

    3种函数参数传递方式 1. 将变量名作为形参和实参 在这种情况下传给形参的是变量的值.传递是单向的,即如果在执行函数期间形参的值发生变化,并不传回给实参,这就是值传递方式.因为在调用函数期间,形参和实 ...

  3. java.函数参数太多,Java方法参数太多怎么办—Part 2—引入参数对象,javapart

    Java方法参数太多怎么办-Part 2-引入参数对象,javapart 目录 自定义类型 引入参数对象 本文是这个系列的第二篇文章,介绍了通过引入参数对象应对参数过多的问题.如果你也希望参与类似的系 ...

  4. java 函数参数 返回值_java中如何用函数返回值作为post提交的参数?

    1.我想实现的功能是在java程序中导入HttpURLConnection类,然后将函数的值作为post方法要提交的参数,最后显示在显示台上. 2.要用到的函数是自己写的可以显示实时计算机cpu.内存 ...

  5. java 参数三点,java函数参数类型后添加三点的用法

    类型后面三个点(String...),是从Java 5开始,Java语言对方法参数支持一种新写法,叫可变长度参数列表,其语法就是类型后跟...,表示此处接受的参数为0到多个Object类型的对象,或者 ...

  6. java函数参数使用冒号_java8中:: 用法示例(JDK8双冒号用法)

    JDK8中有双冒号的用法,就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下. 代码其实很简单: 以前的代码一般是如此的: public class Accep ...

  7. java函数参数 省略号_[转] java使用省略号代替多参数.pdf

    [转] java使用省略号代替多参数.pdf 还剩 7页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: J2SE 1.5提供了"Varargs ...

  8. Python中函数参数传递方式介绍

    一.参数使用介绍 在Python中,类型属于对象,变量是没有类型的.变量仅仅是一个对象的引用(一个指针),可以是List类型对象,也可以是String类型对象 1.1 可更改(mutable)与不可更 ...

  9. c java 传参数_Java和C的方法参数传递方式的比较

    java中的形参是复制实参的一份拷贝(对于引用类型则是复制引用的拷贝,在栈中的拷贝),所以在函数中改变形参是无法改变实参的值的,改变引用只是将形参所代表的引用指向另外的新的对象,而实参的引用还指向原来 ...

  10. C++中的参数传递方式:传值、传地址、传引用总结

    指针:指针是一个变量,只不过这个变量中存储的是一个地址,指向内存中的一个单元. 引用:引用和原变量是同一个东西,只不过是原变量的一个别名. int a = 10; 定义一个整型变量aint *p = ...

最新文章

  1. selenium 无法定位打开a链接_测试干货 :Selenium8种元素定位法
  2. 【每周CV论文】初学GAN图像风格化必须要读的文章
  3. 《数据结构与算法》实验报告——快速排序
  4. 2020年系统集成项目管理工程师上午真题及答案解析
  5. 《Go 语言程序设计》读书笔记 (九) 命令工具集
  6. mysql清除旧版本_MYSQL使用INNODB时及时清理旧版本数据
  7. matlab 读取同一文件中所有图像_matlab 批量读取文件夹内所有图片的几种方法
  8. 使用treeNMS管理及监控Redis
  9. HyperX Savage系列 DDR3 2400 16GB (8GBx2)玩虚拟化部署
  10. 2022年水果市场调查报告分析
  11. sftp工具都有哪些_自媒体都有哪些做图神器?自媒体人常用的工具
  12. 大一上C语言复习3.填空题
  13. 2019.8.7 金华正睿集训总结Day11(ACM)
  14. 【简易搭建个人博客】------- 基于BT面板的个人博客搭建
  15. 奥利给,redis项目中初体验
  16. JS 函数中的 arguments 类数组对象
  17. 设计模式-创建型模式(单例、简工、工方)
  18. 计算机作文我的职业理想300字,我的人生理想作文300字(4篇)
  19. NDS《超级马里奥64DS》全要素攻略
  20. C语言笔记-22-Linux基础-信号

热门文章

  1. Summary_zTree的 setting 配置详解
  2. 利用excel做简单的曲线拟合并生成公式
  3. 百度地图和openlayers融合封装(想法)
  4. asp小偷转html,ASP之XMLHTTP小偷程序的简单代码范例
  5. 计算机控制系统电阻加热课设,计算机控制系统课程设计资料.doc
  6. java贪吃蛇食物_JAVA贪吃蛇课程怎么处理食物的随机性
  7. 12306分流抢票软件 v1.13.21官方版 -抢票神器
  8. Isight 软件集成AVLCruise软件方法探讨
  9. 浅析HEVC/H.265编码器中的熵编码
  10. 基于jsp网上书店设计与实现毕业设计论文