解惑4:java是值传递还是引用传递

解惑4:java是值传递还是引用传递一、概述曾经纠结了很久java的参数传递方式是什么样的,后面粗略的了解了一鳞半爪以后有了大概的印象:“传参数就是值传递,传对象就是引用传递”,后面进一步查找了相关资料和文章以后,发现这么理解是不正确

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、概述

曾经纠结了很久java的参数传递方式是什么样的,后面粗略的了解了一鳞半爪以后有了大概的印象:“传参数就是值传递,传对象就是引用传递”,后面进一步查找了相关资料和文章以后,发现这么理解是不正确的。

这里先放结论:

  • java中参数的传递可以理解为都是值传递
  • 基础数据类型传递的是值的拷贝
  • 对象类型是共享对象传递,传递的是地址的拷贝

二、形参和实参

要理解参数的传递就必须先理解形参和实参:

  • 形参:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的。

    形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元。

    因此,形参只在方法内部有效,所以针对引用对象的改动也无法影响到方法外。

  • 实参:就是实际参数,用于调用时传递给方法的参数

举个例子:

public static void main( String[] args ) {
    String string = "Hello";
    //string是实际参数
    sout(string);
}

public static void sout(String str){
    //str为形式参数
    System.out.println(str);
}

三、值传递和引用传递与共享对象传递

1.值传递和引用传递

理解了实参和形参,以及java对应的数据类型,我们就可以理解值传递和引用传递了。

  • 值传递:方法调用时,实际参数的被传递给对应的形式参数,函数接收的是原始值的一个copy, 此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值

  • 引用传递/址传递:方法调用时,实际参数的地址被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址。在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象

对于这两种方式,网上有一个非常形象的图:

解惑4:java是值传递还是引用传递

2.共享对象传递

但是java的传值策略有点类似于两者的结合,是共享对象传递

  • 共享对象传递:先获取到实际参数的地址,然后将其复制,并把该地址的拷贝传递给被调函数的形式参数。因为参数的地址都指向同一个对象,所以我们称也之为”传共享对象”,所以,如果在被调函数中改变了形式参数的值,调用者是可以看到这种变化的。

这也是之所以说java也是值传递的原因,共享对象传递实际上也是对实参进行拷贝然后赋给形参,但是操作针对的对象不是值而是地址

由于传递的是地址的拷贝,所以如果你在方法中将这个地址指向了新的对象,实际上是没有任何对方法外是没有任何作用的,举个例子:

public static void main( String[] args ) {
    Person p = new Person();
    System.out.println("main中:" + p.hashCode());
    change(p);
    System.out.println("main中:" + p.hashCode());
}

public static void change(Person person){
    person = new Person();
    System.out.println("change中:" + person.hashCode());
}

//输出
main中:692404036
change中:1554874502
main中:692404036

可以看到在main方法中输出的hashCode指向的都是同一个对象,而change中指向了另一个,可以这么理解:

  • p为指向了第一个Person对象的地址
  • 把p拷贝了一份得到p‘,这里的p’就是change方法中的形参p
  • change中p指向了一个新的Person对象,在change这个函数范围里p指向的就是new出来的第二个Person对象的地址
  • 由于change中的p实际上是main中p的拷贝p‘,所以在change里p’指向的改变对main中的p不会有任何影响

四、总结

你在福建有座仓库,给自己配了一把钥匙

1.三种传递:

  • 值传递:你建了一座一模一样的仓库给别人
  • 引用传递:把你家仓库的钥匙给了别人
  • 共享对象传递:把你家仓库钥匙复刻了一把给别人

2.共享对象传递的特点:

  • 拷贝的地址与原地址指向同一个内存对象:别人用你复刻的钥匙一样能进出你的仓库
  • 拷贝地址引用对象的改变不影响原地址的引用对象:老王在福建泉州也盖了个一模一样仓库,钥匙和你的一模一样,虽然你的仓库比较有名,但是唯独在泉州提到仓库大家都想到的是老王的仓库。你说这把钥匙能开仓库,在泉州大家想到是这把钥匙能开老王的仓库,在其他城市大家想到是能开你的仓库
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170798.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 关于MATLAB读取txt文件的方法[通俗易懂]

    关于MATLAB读取txt文件的方法[通俗易懂]关于MATLAB读取txt文件的方法一、如何读取一个文档下,多个txt文件?一般读取的文件,命名都具有一定的规律,除去相同部分,剩下的变化按照时间、序号、某一特定的标志符等进行排列。下面我们举个例子来操作。假如文件夹里存在以下文件:cs20170701cs20170702cs20170703cs20170704…cs20170731标签:cs代表产品类型,数字代表年月日。总共…

    2022年9月6日
    3
  • C语言中u8 u16 u32含义,有关stm32的问题,程序里面的u8、u16这些是什么意思啊「建议收藏」

    C语言中u8 u16 u32含义,有关stm32的问题,程序里面的u8、u16这些是什么意思啊「建议收藏」u8是unsignedchar,u16是unsignedshort,u32是unsignedlong。u8,u16,u32都是C语言数据类型,分别代表8位,16位,32位长度的数据类型,一个字节是8位,所以u8是1个字节,u16是2个字节,u32是4个字节。可以在stm32库头文件中找到数据类型的声明在stdint.h中:typedefunsignedcharuint8_t;typed…

    2022年10月9日
    0
  • 阿里云动态域名_阿里动态域名解析

    阿里云动态域名_阿里动态域名解析前言该脚本的代码大部分是参考自阿里云的官方帮助文档。1,脚本语言使用的是python,我个人只是了解python,没有太深入的知识功底2,脚本代码我会尽量详细地添加注释说明,有问题欢迎留言

    2022年8月5日
    4
  • 【转载】“菜”鸟理解.NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)

    【转载】“菜”鸟理解.NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)

    2021年11月20日
    45
  • python读取txt文件中的json数据

    python读取txt文件中的json数据txt文本文件能存储各式各样数据,结构化的二维表、半结构化的json,非结构化的纯文本。存储在excel、csv文件中的二维表,都是可以直接存储在txt文件中的。半结构化的json也可以存储在txt文本文件中。最常见的是txt文件中存储一群非结构化的数据:今天只学习:从txt中读出json类型的半结构化数据importpandasaspdimportjsonf=o…

    2022年5月18日
    152
  • layui 树形表格 treeTable使用详细指南,不能折叠解决办法

    layui 树形表格 treeTable使用详细指南,不能折叠解决办法最近在写一个商品分类管理的功能,本来想用layui的树形组件来写,但发现layui原生的tree只能展示title,而分类的其他字段无法展示,这就有点不适用了,无意中看到一位大神自定义写的一个树形表格组件,正好满足我的要求,特此将使用方法以及其中遇到的一些坑记录下来。。。首先看下treeTable的演示地址项目地址好了,如果看完演示到这里你觉得正好符合你的功能要求,就可以继续往下看了,虽…

    2022年5月4日
    100

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号