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

createh54个月前 (12-17)技术教程44

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

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

值传递 vs 引用传递

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

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

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

值传递

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

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

引用传递

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

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

Java中的参数传递

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

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

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

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

基础数据类型变量传递

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

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

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

对象类型传递

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

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

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

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

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


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

总结

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

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

相关文章

java面试题|JVM调优常用JVM参数代码实例简介

JVM(Java Virtual Machine)启动参数用于配置Java应用程序的运行时环境,包括内存管理、垃圾回收(GC)算法、性能调优和日志记录等。# JVM启动参数,不换行格式 # 设置堆内...

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

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

JVM 配置参数 -D,-X,-XX 的区别

最近在安全护网行动,需要针对服务进行不断的安全加固,如 对服务的 log4j 的安全配置进行防护,对 fastjson 的漏洞进行安全加固等,最快的防护方法就是通过在服务启动的时候,设置对应的安全参数...