首先,我们必须要搞清楚的一件事是,不管java的参数类型是什么,一律传递的是参数的副本。也就是说每次传递参数的时候都会讲参数拷贝一份传递。
1.基本数据类型:
对于基本的数据类型来说,java传递的是指的副本;也就是将数据拷贝一份以后传递。因此当函数返回的时候,不管在调用的函数中做了什么操作,基本数据类型的值都不会改变。
2.对象型数据类型:
对于对象型数据类型,java传递的则是参数的引用副本,也就是将对象的地址拷贝一份传递,因此,如果在调用的函数中改变了对象的值的话,那么函数返回以后,对象中的值也会跟着改变,如果在函数体重改变了对象的地址,那么函数返回以后由于地址不改变,因此对对象的地址的赋值操作其实也是没有用的。看下面的例子。
class Value{
public int i = 15;
}
public class Test{
public static void main(String [] args){
int i = 5;
Value v = new Value();
v.i = 25;
second(v,i);
System.out.println(v.i)
}
public void sencond(Value v,int i){
i = 0;
v.i = 20;
Value value = new Value();
v = value;
System.out.printin(v.i+" "+ i);
}
}
输出结果为15,0,20.
解析:
当调用second(v,i)函数的时候必须先将函数地址压入堆栈,函数的参数同时也会压堆栈,但是,对于基本数据类型的参数会将参数的实际值压入堆栈,而会将对象型参数的地址压如堆栈。当函数返回的时候,便会将参数从堆栈中取出来,由于对象型参数取出来的还地址,因此,不管在调用函数中做了什么修改地址操作,最后取出来的都是压如堆栈的参数的地址对应的值。同样,对于传值的参数,由于原参数的值直接压如堆栈了,那么函数返回的时候,取出来的还是原压入堆栈的值。这样的话就很好解释上面的程序的输出结果了。