Java方法参数传递的机制 java方法参数可以传空吗

createh55个月前 (12-17)技术教程46

目前两种比较流行的方法参数传递模式主要是值传递引用传递。不同的编程语言对于这两种机制可能有不同的处理方式。对Java来说,一切都是严格按值传递的

接下来,我们来一起探讨下 Java 如何为各种类型传递参数。在此之前,我们先解读下值传递和引用传递的概念。

值传递 vs 引用传递

让我们先看下函数参数传递的不同机制有哪些:

  • 按值
  • 按引用
  • 按结果
  • 按值-结果
  • 按名称

不过目前流行的编程语言中用的最多的就是按值按引用传递,下面具体看下概念:

值传递

当一个参数作为方法的值传递时,被调用的方法其实是拿到了一个传入参数值的拷贝,所以各自的参数变量的修改是互不影响的。

这意味着当你调用一个方法时,传递给被调用方法的参数将是原始参数的克隆。对于被调用方法的任何修改对调用方法中的源参数毫无影响。

引用传递

当一个参数作为方法的引用传递时,调用方法和被调用方法其实操作的是同一个对象。

具体来说就是这个对象的唯一标识将会发送给被调用方法,任何对这个参数实例中的成员进行修改都会影响原始对象的值。

Java中的参数传递

在Java中,基本数据类型变量存储的都是实际的值,但是对于非基础数据类型(比如:类)变量存储的是指向这个对象的地址引用。不管是值还是引用它们都存储在栈内存中

对于Java的方法参数来说总是严格按照值传递方式(copy模式)来处理的。因为在方法调用的期间,不管这个参数类型是值还是引用都会拷贝一个副本并且会在栈内存中开辟一个空间,然后在传递给目标方法。

对于基础数据类型变量来说,就是简单的拷贝一个值到栈内存,然后再传递给目标方法。对于非基础数据类型变量来说,就是一个栈内存的引用并指向存放在堆中的实际对象,当我们传递这个对象时,实际传递的是这个对象对应的栈内存引用的副本。

还是以具体代码案例来说明吧:

基础数据类型变量传递

Java编程语言具有八种基本数据类型。基础数据类型会直接存储在栈内存中。任何基础类型的变量不管在什么时候作为参数传递时,实际的参数都会拷贝到形式参数中并且这些形式参数在栈内存中都有自己的独立空间。

这些形式参数的的生命周期会仅仅在该方法运行期间存在,随着方法执行return后将从堆栈中清除并丢弃。

通过上图可以看出,目标方法pasbyValue中对变量i进行修改后并不影响调用方法中的变量i,栈的示意图也表明目标方法中的变量i完全是一个新的值,所以不管怎么修改都不会影响源值。

对象类型传递

在Java中,所有的对象都会存储在堆空间中。这些对象会被称为“引用变量”的引用而引用。

与基础类型存储方式不一样,Java对象会被存储在两个不同的地方。引用变量会被放在栈内存中而被引用的对象会被存储在堆内存中。

每当将对象作为参数传递时,就会创建一个引用变量的副本并指向一个堆内存的对象,这个堆内存对象就是原始引用的对象,简单来说就是两个引用同时指向同一块堆内存区域

所以我们得出一个结论就是,每当我们对传递过来的对象进行修改时都会导致原始对象的改变。但是,如果我们对传递的引用重新赋予一个新的对象,此时原始对象是不会受影响的(引用副本指向了一块新的堆内存区域)

下图为目标方法仅仅修改对象的属性:


下图为目标方法为引用重新复制一个新的对象:

总结

通过以上的解释和演示,我们知道Java中的参数传递总是按值传递,对于方法执行参数结果的变化取决于传入的是基础数据类型还是对象:

  • 对于基础数据类型,参数按值传递
  • 对于对象类型,对象的引用是按值传递,但是我们要注意按值传递后的应用会不会指向新的对象,这个是值得我们关注的地方

相关文章

JVM诊断之查看运行参数 jvm运行参数说明

问题描述为了分析和定位一个Java线上系统问题,我们需要查看JVM启动时的一些参数设置,例如:垃圾回收算法、堆大小等等。这些参数可能在启动脚本中明确指明,也可能采用默认值。在系统运行过程中其他人也许动...

JVM三大性能调优参数Xms,Xmx,Xss的含义,你又知道多少呢

我们在程序运行中,经常会遇到各种各样的问题,比如说,我们会遇到内存大小需要调,或者说并发线程数需要调整,遇到这个情况的时候该怎么办呢,接下来我们就一起学习怎么给JVM调优。JVM三大性能调优参数 -X...

Nginx 转发时的一个坑,运维居然让我背锅

最近遇到一个 Nginx 转发的坑,一个请求转发到 Tomcat 时发现有几个 http header 始终获取不到,导致线上出现 bug,运维说不是他的问题,这个锅我背了。新增的几个 header...

微信支付报"调用支付jsapi缺少参数 total_fee",实际Java统一

微信支付报"调用支付jsapi缺少参数 total_fee",实际Java统一支付接口,返回“body参数长度有误”之前帮朋友做过一次微信支付,记得里面到处都是坑,今天朋友说出现问题提...