关于Java中传递参数的若干问题

       学过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。

 

关于Java中传递参数的若干问题,布布扣,bubuko.com

关于Java中传递参数的若干问题

上一篇:Java设计模式之从星际争霸1分析抽象工厂模式


下一篇:由不同编号生成策略产生的多线程问题及解决