Java中传递参数的若干问题

来源:互联网 发布:阿里云ecs是什么 编辑:程序博客网 时间:2024/06/13 22:04

       学过C/C++的人或多或少会对Java中传递参数产生一定的困惑。下面我以读书笔记的形式谈谈自己对Java中传递参数问题的一些认识。

       学过C系语言的人会说:“参数传递分为传值与传地址:传值形式形参改变不影响实参;传址形式形参改变很有可能影响实参的改变“;

       学过Java的人 则会说:”在Java中只有传值一种方式:如果是基本类型,传递的参数是基本类型的值,在方法中不能改变实参的值;如果是定义的对象,传递的对象的引用,你也不能在方法中修改这个引用,但可以通过该对象的方法改变对象的值。

      两者似乎有很大的区别,甚至产生冲突,且听我慢慢解释。

       

        当传递的是基本数据类型时,二者是统一的。下面C系与Java所得结果相同。

C系:

#include<iostream>using namespace std;void Change(int tempPar){tempPar=10;cout<<"In the function:  "<<tempPar<<endl;}int main(){int par=5;cout<<"Before the function:  "<<par<<endl;Change(par);  cout<<"After the function:  "<<par<<endl;return 0;}


Java:

package JavaLanProtocol;public class Method {public static void main(String []agr){int par=5;System.out.println("Before the function:  "+par);Change(par);System.out.println("After the function:  "+par);}public static void Change(int tempPar){tempPar=10;System.out.println("In the function:  "+tempPar);}}

    结果都为:

Before the function:  5
In the function:  10
After the function:  5 

 

      当传递的是对象时,C系语言中分传值与传地址两种方式,大家都知道,在此就不解释了。但Java中传递的是引用,引用可以理解为地址,最终二者指向同一内存单元。先看段代码:

package JavaLanProtocol;public class Method {public static void main(String []agr){StringBuffer str = new StringBuffer("Hello");  System.out.println("Before the function:  "+str);Change(str);System.out.println("After the function:  "+str);}public static void Change(StringBuffer tempStr){tempStr=(new StringBuffer("World!")); System.out.println("In the function:  "+tempStr);}}

上面代码的输出结果为:

Before the function:  Hello
In the function:  World
After the function:  Hello

       有人可能不解,不是说Java中在此种情况下传递的是对象的引用,为什么”After the function:  Hello“?应该是"After the function: World"才对啊!首先,此时传递的是确实是对象str的引用,即tempStr和str指向同一内存。但为什么最后tempStr和str结果不一样呢?原因在于在“tempStr="World";”执行后,tempStr指向“World”的地址,所以str的只并未改变。此时可以通过调用对象的方法改变原对象的值。

package JavaLanProtocol;public class Method {public static void main(String []agr){StringBuffer str = new StringBuffer("Hello");  System.out.println("Before the function:  "+str);Change(str);System.out.println("After the function:  "+str);}public static void Change(StringBuffer tempStr){tempStr.append("   World!"); 
System.out.println("In the function:  "+tempStr);}}

上述代码执行后结果为:

Before the function:  Hello
In the function:  Hello   World!
After the function:  Hello   World!

       此时str的只改变了,原因在于通过对象引用调用对象的方法改变原对象的值。为什么呢?此时tempStr和str指向同一内存,执行“tempStr.append("   World!");”后,在原有对象的某位加上“   World”。

       上述结果不同的区别在于前者tempStr指向了其他内存单元,而后者始终指向同一内存单元。下面看看以下代码:

package JavaLanProtocol;public class Method {public static void main(String []agr){String str=new String("Hello");System.out.println("Before the function:  "+str);Change(str);System.out.println("After the function:  "+str);}public static void Change(String tempStr){tempStr.toUpperCase();System.out.println("In the function:  "+tempStr);}}


结果是:

Before the function:  Hello
In the function:  Hello
After the function:  Hello

      可能与有些人的想法不一样,他们可能认为应是:

Before the function:  Hello
In the function:  HELLO

After the function:  HELLO

      其实不然,String是不可变的,是const变量。
   

      下面再看一个例子:

package JavaLanProtocol;public class Method {public static void main(String []agr){StringBuffer str = new StringBuffer("Hello");  System.out.println("Before the function:  "+str);Change(str);System.out.println("After the function:  "+str);}public static void Change(StringBuffer tempStr){tempStr.append("  World");StringBuffer temp=new StringBuffer("World");tempStr=temp;temp.append("  Hello");System.out.println("In the function:  "+tempStr);}}

      如果一眼就能看出结果是:

Before the function:  Hello
In the function:  World  Hello
After the function:  Hello  World

     那就OK。

 

0 0
原创粉丝点击