您的位置:首页 > 编程语言 > Java开发

java笔记-函数参数传值

2016-08-30 16:12 351 查看
java中存在引用,但是对于Java中的方法参数传递,无论传递的是原生数据类型还是引用类型,统一是传值(pass
by value


下面举个常见的程序小代码:

public class ParamTest{
public void changePoint(Point point){
point = new Point();
point.x = 3;
point.y = 4;
}

public static void main(String[] args){
ParamTest pt = new ParamTest();
Point point = new Point();
pt.changePoint(point);

System.out.println(point.x);
System.out.println(point.y);
}
}

class Point{
int x;
int y;
}



运行的结果如上

分析:


1.首先在main()方法中声明一个point,指向new的对象(x=0,y=0),这里在java中类的field会默认为0;

2当main()中的point传到changePoint()时会再次声明一个point,此时也指向对象(x=0,y=0);注意这里即发生了参数传递

3.在changePoit()的point指向新建对象(x=3,y=4);

因为是值传递,所以当函数调用结束时changePoint()没有对原来main()中的point产生影响,结果是:0 0;但在changePoint()中打印point值时显然是:3 4

***********************************************************************************************************************************************************

下面代码可以测试理解的程度,原理是一样的

public class People{
int age;

public void change(int i){
i++;
}

public void change2(People p){
p = new People();
p.age++;
}

public void change3(People p, int i){
p.age++;
i++;
}

public static void main(String[] args){

People people = new People();
people.change1(people.age);
System.out.println(people.age);
*****************************
0
*****************************

People people = new People();
people.change2(people);
System.out.println(people.age);
*************************
0
*************************

People people = new People();
people.change3(people,people.age);
System.out.println(people.age);
*******************************
1
*******************************
}
}

*******************************************************************************************************

上面的例子讲解的可能当时不是很理解,有些难以理解,下面再做些补充。

注意    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和不,并不是swap方法中的a和b.也就是说swap方法的a和只是main方法中的复制品Java程序从main方法开始执行,main方法开始定义了a、b两个局部变量,当程序执行到swap方法时,系统进入swap方法,并将main方法中的a、b变量作为参数传到swap方法中,传入的只是swap方法的只是a/b副本,而不是a、b本身,进入swap方法后系统产生了4个变量,main栈区的a和b,swap栈区的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,比属性的值是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对象的a、b两个属性值,所以我们才能看到main方法中dw变量所引用的DataWrap对象的a、b两个属性值也被交换了。

这里利用反射的特性,还可以做一些扩展,下回分析。。。。。

参考:http://blog.csdn.net/xiaoyu714543065/article/details/8064396
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: