已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
353附录1 参数传递附录1 参数传递1.1传值还是传引用Java中的参数传递容易引起混淆,尤其是对于那些有过C/C+经历的读者。在C/C+中参数传递既有传值,又有传引用,而在Java中只存在传值方式的参数传递,但是由于Java中又有引用的概念,这就使得参数传递容易引起初学者的混淆。本节以实例详细分析了参数传递过程,力求给读者一个清晰的认识。下面先从较简单的基本变量类型的参数传递谈起。1.2基本数据类型的参数传递先来看下面这段代码:public class ParaTestpublic static void changeValue(int x) /x称为形式参数 x+; 在应用程序的某个地方,存在如下调用:int bonus=100; ParaTest.changeValue(bonus); / bonus称为实际参数 当上面两行代码执行完毕后,bonus的值是什么呢?答案是bonus仍为100。我们来详细分析一下为什么是这个结果:执行int bonus=100后,变量bonus的值为100(图1.1(a)。当执行语句ParaTest.changeValue(bonus)时,由于Java使用传值方式传递参数,所以bonus的值将首先复制一份传递给x,这时计算机的存储区中会同时存在两个独立的变量bonus和x,并且这两个变量的值相等(图1.1(b)。执行changeValue的方法体时,x的值增加了1,由于bonus和x是两个独立的变量,因此x值的增加不会影响到bonus(图1.1(c)。当方法执行完毕后,x不再有效,但bonus的值没有改变(图1.1(d)。所有基本数据类型的参数传递都和上述过程类似,为此可以有如下结论:当参数为基本数据类型时,参数传递时将实际参数的值复制一份传递给方法的形式参数,形式参数值的改变不会影响所传入实际参数的值。图1.1 基本变量类型的参数传递 1.3对象数据类型的参数传递1.3.1 参数为单个对象下面来看一下参数为对象数据类型时是什么情况:首先生成一个字符串对象:String aStr=new String(abc); 由前面的知识我们已经知道,对象变量aStr是指向字符串对象“abc”的一个引用。 这时,如果类ParaTest中有一个方法:public static void changeStr(String str) /str为形式参数 str=str+cde;在应用程序的某个地方,存在如下调用:String aStr=new String(abc);ParaTest.changeStr(aStr); /aStr为实际参数那么当上面两行代码执行完毕后,aStr所指对象的内容是什么呢?有的读者可能会这样分析:由于aStr是指向字符串对象“abc”的一个引用,在调用方法changeStr后,aStr所指对象的字符串变为了“abccde”。这样的分析看似正确,实际上不正确。正确的结论是,aStr所指对象的字符串仍然为“abc”。 我们来分析一下:当执行完语句String aStr=new String(abc)时,对象变量aStr指向字符串对象“abc” (图1.2(a);执行语句ParaTest.changeStr(aStr)时,尽管aStr 是对象的一个引用,但由于Java使用传值方式传递参数,所以aStr的值(对象的引用)将首先复制一份传递给对象变量str,这时计算机的存储区中会同时存在两个独立的对象变量aStr和str,这两个对象变量均指向字符串对象“abc” (图1.2(b)。执行changeStr的方法体时,系统新生成一个字符串对象“abccde”并赋值给str,这时str将指向对象“abccde”(图1.2(c)。 由于aStr和str是两个独立的对象变量,str所指对象的改变并不会影响到aStr所指的对象,即aStr仍旧指向原来的字符串对象“abc”。当方法执行完毕后,str不再有效,会在适当的时候被回收,但aStr所指对象依旧没有改变(图1.2(d)。 图1.2 状态不可转换对象变量类型的参数传递到这里问题是不是就结束了呢?下面再来看一个例子:如果类ParaTest中有一个方法:public static void changeStrBuf(StringBuffer str) str.append(cde); 在应用程序的某个地方,存在如下调用:StringBuffer aStrBuf=new StringBuffer(abc);ParaTest.changeStrBuf(aStrBuf);那么当上面两行代码执行完毕后,aStrBuf所指的对象是什么呢?按照上面的分析,有的读者或许会认为aStrBuf所指的对象不变,仍为“abc”。但实际上正确的结果是aStrBuf所指的对象变为“abccde”。为什么会是这样呢?这个例子和上面一个例子最重要的一个区别在于方法体中的语句:本例的方法体中的语句str.append(cde)直接调用str所指对象中的方法append,改变了所指对象为“abccde”,而不是像上例中那样让str指向了一个新对象(图1.3(a)1.3(d)。图1.3 状态可转换对象变量类型的参数传递到了这里,读者不禁要问,究竟什么时候一个方法可以改变传递进来的对象呢?为了更好的回答这个问题,这里先给出两个定义:状态可转换对象:如果一个对象中存在改变对象本身状态(所存储的内容)的方法,则称该对象为状态可转换对象。如StringBuffer类型的对象中存在append方法来改变对象的状态,所以StringBuffer类型的对象是状态可转换对象。状态不可转换对象:如果一个对象中不存在改变对象本身状态的方法,则称该对象为状态不可转换对象。如String类型的对象中不存在任何方法来改变对象的状态,要改变String类型的对象的状态必须生成新的String对象,所以String类型对象是状态不可转换对象。更简单地说,如果一个对象可以在不改变其在内存中的存储位置的情况下而改变其本身的状态,就是状态可转换对象。否则就是状态不可转换对象。有了上面的定义,我们可以得出如下结论:如果一个方法接收的参数为状态可转换对象,那么该方法可以通过调用该对象中适当的方法来改变实际参数的状态;如果一个方法接收的参数为状态不可转换对象,那么该方法不可以改变实际参数的状态。结合上面的分析,请读者编译、运行下面的程序,并查看运行结果:例1.1 ParaTest.javapublic class ParaTestpublic static void changeValue(int x)x+;public static void changeStr(String str)str=str+cde;public static void changeStrBuf(StringBuffer str)str.append(cde);public static void main(String args)/基本变量类型的参数传递int bonus=100;System.out.println(before pass: bonus=+bonus);ParaTest.changeValue(bonus);System.out.println(after pass: bonus=+bonus);/状态不可转换对象变量类型的参数传递String aStr=abc;System.out.println(before pass: aStr=+aStr);ParaTest.changeStr(aStr);System.out.println(after pass: aStr=+aStr);/状态可转换对象变量类型的参数传递StringBuffer aStrBuf=new StringBuffer(abc);System.out.println(before pass: aStrBuf=+aStrBuf);ParaTest.changeStrBuf(aStrBuf);System.out.println(after pass: aStrBuf=+aStrBuf);1.3.2 参数为对象数组 先来看下面的swap方法,该方法试图交换所传入的两个对象:public static void swap(Object a, Object b)Object temp=a;a=b;b=temp;在应用程序的某个地方,存在如下调用:String aString=aaa;String bString=bbb;System.out.println(before swap: aString=+aString+ bString=+bString);swap(aString,bString);System.out.println(after swap: aString=+aString+ bString=+bString);通过1.3.1小节的分析,我们已经知道,swap方法不能完成两个字符串对象的交换,读者可以自行以图解方式分析之。执行上面代码片断的输出是:before swap: aString=aaa bString=bbbafter swap: aString=aaa bString=bbb再来看下面的swapArray方法,该方法将对象数组中位置为i和j的两个数组元素进行交换:public static void swapArray(Object a,int i,int j)if(i!=j)Object temp=ai; /(1)ai=aj; /(2)aj=temp; /(3)在应用程序的某个地方,存在如下调用:String strArray=tom,jerrey;System.out.println(before swap: strArray0=+strArray0+ strArray1=+strArray1);swapArray(strArray,0,1);System.out.println(after swap: strArray0=+strArray0+ strArray1=+strArray1);可以发现,上述代码片断的输出为:before swap: strArray0=tom strArray1=jerreyafter swap: strArray0=jerrey strArray1=tom也就是说,swapArray方法确实完成了对象数组中两个不同对象之间的交换。为什么swap方法不能完成两个对象的交换,而swapArray方法可以呢?同样,这里以图解的方式来进行分析:初始时,strArray的存储情况如图1.4(a)所示。随后,strArray的值复制一份传递给形式参数a(图1.4(b)。swapArray方法中的三条语句依次执行的结果见图1.4(c)。swapArray方法返回后,a和temp都不再有效,因此最终的结果如图1.4(d)。例1.2 给出了完整的例子代码。图1.4 对象数组类型的参数传递例1.2 ObjectArray.javapublic class ObjectArraypublic static void main(String args)String aString=aaa;String bString=bbb;System.out.println(before swap: aString=+aString+ bString=+bString);swap(aString,bString);System.out.println(after swap: aString=+aString+ bString=+bString);String strArray=tom,jerrey;System.out.println(before swap: strArray0=+strArray0+ strArray1=+strAr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 掌握海南时事:重要试题及答案公布
- 《地震》分层作业及答案-2026-2027学年湘科版(新版)小学科学五年级上册
- 国际土著人日民族团结
- 2026年推普周啄木鸟行动课件
- 某麻纺厂原料储存规范
- 某造纸厂环保排放规范
- 某电信厂数据备份办法
- 某麻纺厂财务风险控制办法
- 某家具厂成本控制制度
- 2025年7月国家开放大学汉语言本科《中国现代文学专题》期末纸质考试试题及答案
- (2026年秋)人教版七年级上册英语单词表
- 义务教育英语课程标准解读完整版课件小学初中版
- 2026年安徽省中考英语试题(含答案)
- 【财务岗位审计对接人员】【年报季报审计场景】【资料准备混乱调整分录不规范沟通成本高昂】【审计准备手册与调整分录工具包】
- 2026年电焊工技能比武理论考试试题(含答案)
- 2026年陕西二级造价工程师土建工程考试真题及答案
- 眼外伤的紧急处理与后续护理
- 新课程视域下小学语文教材助学系统的深度剖析与实践应用
- 2026年大学生人文知识竞赛题库及答案
- 智慧楼宇管理员培训课件
- 《2026年》科研管理岗位高频面试题包含详细解答
评论
0/150
提交评论