首页 > 编程语言 >Java是值传递还是引用传递?

Java是值传递还是引用传递?

时间:2024-03-12 20:59:46浏览次数:28  
标签:副本 Java 传递 参数 引用 方法

1、典型回答

值传递(Pass by value)和引用传递(Pass by reference)是关于参数传递方式的两个概念

  • 值传递:将传递参数的值,复制一份到方法的参数中。换句话说,值传递的是原始数据的一个副本,而不是原始数据本身
  • 引用传递:将实际参数的引用(内存地址)传递给方法,这意味着方法内部对参数的修改会影响原始数据本身,也就是说引用传递传递的是原始数据,而非原始数据的副本

也就是说,值传递和引用传递最大的区别是传递的是自身,还是复制的副本,如果传递的是自身,则为引用传递,如果传递的是复制的副本,则为值传递

在 Java 语言中,只有值传递,没有引用传递!

例如,在以下示例中,传递基础数据类型 int 的参数,之后修改传递的参数,然后再在原来的方法中,打印参数的结果,实现代码如下:

以上程序的执行结果如下:

从上述结果可以看出 int 是值传递

如果说,上面传递的是基本数据类型,接下来我们传递一个对象(引用类型):

 以上程序的执行结果如下:

 从上述结果可以看出,当传递的是 Integer 对象时,其依然是值传递,所以在 Java 语言中,并没有引用传递

因此,无论是基础数据类型,还是引用数据类型(对象),都为值传递,而非引用传递

2、全面剖析

值传递和引用传递的关键是,传递的是副本还是其本身,如果是副本则为值传递,如果是其本身则为引用传递,而 Java 语言中,只有值传递,也就是说它始终传递的都是副本

那么,问题来了,为什么在以下代码中,当我传递的是一个数组的时候,就和之前的结果不一样了呢?

以上程序的执行结果为:

调用方法前:磊哥

方法中修改为:磊神

调用方法后:磊神

这样就出问题了,当传递了数组之后,明显是 “引用传递”,而非值传递,这到底是怎么回事?

别着急,当我们把新方法中的代码做了以下调整之后,运行结果又不一样了,如下代码所示:

以上程序的执行结果为:

调用方法前:磊哥

方法中修改为:磊神

调用方法后:磊哥

你会发现,当我们在新方法中仅仅添加了一行 “n = new char[2]; ”代码时,它又变成了值传递,这是怎么回事?

原因分析

如果是引用传递,那么我在新方法中无论如何修改,那么都应该是影响原对象才对,而刚才我稍微调整了代码之后就发现并非引用传递,而是值传递,这是因为当传递数组时,其传递的是 “引用副本”,而非真正的引用对象(也就是其本身)

也就是说,当传递数组时,其实传递的是“引用副本”,注意是 “引用” 的副本。然后新方法通过这个副本指向原数组。不是对象本身的副本!!!是对象引用的副本!!!如下图所示:

然而,在调用了“n = new char[2]; ”代码之后,给变量在堆上创建了新对象,此时就不再使用原来的引用副本了,这个时候,再修改新方法中的变量就不影响原变量了,如下图所示:

所以,在Java中,只有值传递,它始终传递的都是副本,而非原(引用)对象 

3、知识扩展

3.1、形参 VS 实参

在 Java 中,形参(formal parameters)和 实参(actual arguments)是方法定义和方法调用中的两个概念,形参是方法定义中声明的参数,用于接受方法调用时传递的实参的值,而实参是方法调用时提供给方法的具体参数值

3.2、参数类型:固定个数参数和可变参数

在 Java 中,方法的参数可以有以下几种类型:

  1. 基本数据类型参数:包括整型(byte、short、int、long)、浮点型(float、double)、字符型(char)以及布尔型(boolean)等
  2. 引用类型参数:包括类、接口、数组等。引用类型的参数实际上传递的是对象的引用值,而不是对象本身
  3. 泛型参数:Java5 及以上版本引入的泛型机制可以用于定义带有参数化类型的方法。这样可以在方法中使用泛型进行更加灵活的类型处理
  4. 可变参数(Varargs)参数:Java5 及以上版本引入的一种特殊的参数类型,在方法声明中使用...表示。它允许方法接受可变数量的同类型参数,将这些参数作为数组进行处理

以上类型中,前三种属于固定参数类型,而最后一种为可变参数类型

标签:副本,Java,传递,参数,引用,方法
From: https://blog.csdn.net/dream_ready/article/details/135633484

相关文章

  • 【华为OD机试】真题B卷-分班问题(JAVA)
    华为OD机试真题汇总目录  【华为OD机试】真题汇总A+B+C+D券(Python实现)  【华为OD机试】真题汇总A+B+C+D卷(JAVA实现)  【华为OD机试】真题汇总A+B+C+D卷(C++实现)一、题目题目描述:幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小......
  • 01-Java程序基础
    标识符与变量标识符标识符可以标志:类名,方法名,接口名,常量名命名规则:只能由字母,数字,下划线,$组成不能以数字开头关键字不能做标识符标识符严格区分大小写例如:classHelloWorld{}classhelloWorld{}这两个类是完全不同的类,但如果用javac编译这个文件仅......
  • JavaEE开发环境配置(1)
    JavaEE开发环境配置(1)一、实验目的二、实验用的仪器和材料三、实验的步骤和方法四、数据记录和计算五、实验结果或结论六、总结一、实验目的(1)掌握JDK、Maven、Tomcat、Idea等开发环境的安装和配置(2)理解Servlet的基本原理(3)掌握Servlet项目的配置和运行方法二、实验......
  • java毕业设计五邑大学超市网上销售软件设计(Springboot+mysql+jdk1.8+maven3.39)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的飞速发展,电子商务已经成为现代商业活动中不可或缺的一部分。特别是网上超市销售业务,它借助网络平台突破了传统购物的时间和空间限制,为消......
  • JAVA实现算法问题25匹马,找出最快的3匹,但是只有5个赛道,每次比赛只能得到5匹马的速度排
    JAVA实现算法问题25匹马,找出最快的3匹,但是只有5个赛道,每次比赛只能得到5匹马的速度排序,那么最少需要多少次比赛随机数模拟25匹马匹速度importjava.lang.reflect.Array;importjava.util.Arrays;publicclassMa{publicstaticvoidmain(String[]args){......
  • 【使用docker 搭建Java仓库 nexus 】
    yaml---apiVersion:apps/v1kind:StatefulSetmetadata:annotations:k8s.eip.work/displayName:Nexus服务k8s.eip.work/ingress:'false'k8s.eip.work/service:ClusterIPk8s.eip.work/workload:nexuslabels:k8s.eip.work/layer......
  • java018学习记录
    JavaWeb前端+后端+数据库DBDataBase数据库是一个服务,启动服务才能使用,开机自动启动,存储业务数据关系型数据库,传统数据,主要的业务数据,MySQL、Oracle、SQLServer(C#)结构复杂、性能稳定、速度较慢非关系型数据库,MongoDB、Redis结构灵活、速度快,功能有限,查询次数比......
  • java眉山市白果村鲜茶供销管理(ssm)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:位于四川省眉山市的白果村,是一个以种植业为主的传统农业村落。近年来,随着农业结构的调整和市场需求的变化,白果村开始大力发展茶叶产业,尤其是鲜茶的生产与......
  • java煤矿安全管理信息系统(ssm)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在煤炭开采过程中,由于作业环境的复杂性以及作业过程的危险性,煤矿安全管理一直是全球范围内矿业安全领域的重要课题。传统的煤矿安全管理多依赖于人工监测......
  • java美达外卖平台(ssm)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在当今快节奏的生活中,外卖服务已成为城市居民日常生活的一部分。随着互联网技术的飞速发展和智能手机的普及,传统的电话订餐方式逐渐被各种便捷的在线订餐......