Java方法参数传递(Java swap函数)

news/2024/7/4 0:55:28 标签: java, class, string, null
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

       Java里方法的参数传递方式只有一种:值传递。值传递,就是将实际参数值的副本(复制品)传入方法内,而参数本身不会受到任何影响。

      public class PrimitiveTransferTest

      {

            public static void swap(int a,int b)

             {

                     int temp=a;

                     a=b;

                     b=temp;

                     System.out.println("swap方法里,a的值是"+a+";b的值是"+b);

              }

              public static void main(String args[])

              {

                      int a=6;

                      int b=9;

                      swap(a,b);

                      System.out.println("交换结束后,变量a的值是"+a+";变量b的值是"+b);

               }

          }

          运行结构:

          swap方法里面,a的值是9;b的值是6;

          交换结束后,变量a的值是6;变量b的值是9;

         从运行结果可以看出,main方法里面的变量a和b,并不是swap方法里面的a和b。,也就是说swap方法的a和b只是main方法里面变量a和b的复制品。

          Java程序从main方法开始执行,main方法开始定义了a、b两个局部变量,当程序执行swap方法时,系统进入swap方法,并将main方法中的a、b变量作为参数值传入swap方法,传入swap方法的只是a/b的副本,而不是a、b本身,进入swap方法后系统产生了4个变量,main栈区的a和b,swap栈区的a和b。

        在main方法中调用swap方法时,main方法还未结束。因此,系统分别为main方法和swap方法分配两块栈区,用于保存main方法和swap方法的局部变量。main方法中的a、b变量作为参数值传入swap方法,实际上是在swap方法栈区中重新产生了两个变量a、b,并将main方法栈区中a、b变量的值分别赋给swap方法栈区中a、b参数(就是对swap方法的a、b形参进行了初始化)。此时,系统存在两个a变量,两个b变量,只是存在于不同的方法栈区中而已。两个输出,一个是输出swap方法中的a、b,一个是main方法中的a、b,程序只是改变的是swap方法中的a、b,而main方法中的a、b并没有改变。这就是值传递的实质:当系统开始执行方法时,系统为形参执行初始化,就是把实参变量的值赋给方法的形参变量,方法里操作的并不是实际的实参变量。

       前面是基本类型的参数传递,Java对于引用类型的参数传递,一样采用的是值传递方式。

       class DataWrap

       {

            public int a;

            public int b;

       }

       public class ReferenceTransferTest

       {

            public static void swap(DataWrap dw)

            {

                     int tmp=dw.a;

                     dw.a=dw.b;

                     dw.b=tmp;

                     System.out.println("swap方法里,a 属性的值是"+dw.a+";b属性的值是"+dw.b);

            }

            public static void main(String args[])

            {

                    DataWrap dw=new DataWrap();

                    dw.a=6;

                    dw.b=9;

                    swap(dw);

                    System.out.println("交换结束后,a属性的值是"+dw.a+";b属性的值是"+dw.b);

            }

  }

     运行结果:

     swap方法里,a属性的值是9;b属性的值是6

     交换结束后,a属性的值是9;b属性的值是6

      从运行结果来看,swap方法和main方法的a、b两个属性值都被交换了,这很容易造成一种错觉:调用swap方法时,传入swap方法的就是dw对象本身,而不是它的复制品。但这只是一种错觉。

      程序从main方法开始执行,main方法开始创建了一个DataWrap对象,并定义了一个dw引用变量来指向DataWrap对象,这是一个与基本类型不同的地方。创建一个对象时,系统内存中有两个东西:堆内存中保存了对象本身,栈内存中保存了引用该对象的引用变量。接下来,main方法中开始调用swap方法,main方法并未结束,系统会分别开辟出main和swap两个栈区,用于存放main和swap方法的局部变量。调用swap方法时,dw变量作为实参传入swap方法,同样采用值传递方式:把main方法里dw变量的值赋给swap方法里dw形参,从而完成swap方法的单位形参的初始化。值得指出的是,main方法的dw是一个引用,它保存了DataWrap对象的地址值,当把dw的值赋给swap方法的dw形参后,即让swap方法的dw形参也保存这个地址值,即也会引用到堆内存中的DataWrap对象。当程序在swap方法中操作dw形参时,由于dw只是一个引用变量,故实际操作的还是堆内存中的DataWrap对象。此时,不管是操作main方法里的dw对象,还是操作swap方法里的dw参数,起始都是操作它所引用的DataWrap对象,它们操作的是同一个对象。因此,当swap方法中交换dw参数所引用的DataWrap对象的a、b两个属性时,我们可以看到main方法中dw变量所引用的DataWrap对象的a、b两个属性值也被交换了。

       为了更好地证明main方法中的dw和swap方法中的dw是两个变量,我们在swap方法的最后一行增加如下代码:

      dw=null;//把dw直接赋值为null,让它不再指向任何有效地址

      然后,main方法调用了swap方法后,再次访问dw变量的a、b两个属性,依然可以输出9、6。把swap方法中的dw赋值为null后,swap方法中失去了DataWrap的引用,不可在访问堆内存中的DataWraper对象。但main方法中的dw变量不受任何影响,依然引用DataWrap对象,所以依然可以输出DataWrap对象的a、b属性值。

       


http://www.niftyadmin.cn/n/1759694.html

相关文章

SpringBoot - Web开发

1. SpringBoot对静态资源的映射规则 在SprigBoot中对于WebMVC的自动配置都在WebMvcAutoConfiguration中 在WebMvcAutoConfiguration中的addResourceHandlers配置了资源映射 Override public void addResourceHandlers(ResourceHandlerRegistry registry) {if (!this.resourc…

081_使用 awk 编写的 wc 程序

#!/bin/bash#自定义变量 chars 变量存储字符个数,自定义变量 words 变量存储单词个数#awk 内置变量 NR 存储行数#length()为 awk 内置函数,用来统计每行的字符数量,因为每行都会有一个隐藏的$,所以每次统计后都1#wc 程序会把文件结尾符$也统计在内,可以使用 cat -A 文件名,查看…

两个有序数组合并为一个有序数组

思想:先依次比较两个数组,按照小的就传入新的数组。当这次比较完之后可能有一个数组的长度很长,留下一些数组,然后在新数组的末尾插入即可。 1 class ArraySort 2 { 3 //两个有序数组的合并函数 4 public static int[…

SpringMVC - 视图解析器

1. 概述 当我们对SpringMVC控制的资源发起请求时,这些请求都会被SpringMVC的DispatcherServlet处理,接着spring会分析看哪一个HandlerMapping定义的所有请求映射中存在对该请求的最合理的映射。然后通过该HandlerMapping取得其对应的Handler&#xff0c…

Python之获取文件夹中文件列表以及glob与fnmatch模块的使用

获取文件夹中的文件列表 print(os.listdir("../secondPackage")) # [__init__.py, secondCookBook.py, 文件与IO.py, testPackage, 迭代器与生成器.py] # 注释: curdir . pardir .. print(os.listdir(os.curdir)) # [__init__.py, secondCookBook.p…

SpringMVC - 静态资源访问

Java项目读取resources资源文件路径那点事 1. servlet-mapping的三种配置方式 *① / ** 拦截所有 jsp js png .css 真的全拦截,因为全拦截了所以对于jsp的某些转发也会被解析 不建议使用 **② .action .do ** 拦截以do action 结尾的请求 **③ / ** 拦截所有,不…

debug_backtrace

说明: 产生一条回溯跟踪 //1.php function test($str) {echo \nHi:.$str;var_dump(debug_backtrace()); } test(friend); //2.php include_once ./1.php; include_once ./2.php; 打印结果:最内部文件是第一个数组,最外部文件是最后一个数组 \nHi:friend …

SpringMVC - Restful

Restful REST:Representational State Transfer 直接翻译:表现层状态转移,REST描述的是在网络中client和server的一种交互形式;REST本身不实用,实用的是如何设计 RESTful API(REST风格的网络接口&#xff…