面向对象之值传递

来源:互联网 发布:苹果软件开发培训 编辑:程序博客网 时间:2024/06/04 19:55

在Java中方法的参数传递方式只有一种,那就是值传递.所谓的值传递,就是在向方法的形参传递实际参数的时候,是传递实际参数的副本,而对参数本身没有任何影响,在这里,主要分为两种值类型的传递.

第一种是基本数据类型的传递

这是比较容易理解的一种值传递,比较经典的例子就是swap方法用来交换两个值.

public class testInt{

       public staticvoid swap(int a,int b){

              int temp= 0;

              temp = a;

              a = b;

              b = temp;

              System.out.println("在swap函数内部的a = " + a +" b="+b);

 

       }     

       public staticvoid main(String[] args){

              int a= 1;

              int b= 2;

              System.out.println("运行swap函数之前的a = " + a +" b="+b);

              swap(a,b);

              System.out.println("运行了swap函数之后的a = " + a +" b="+b);

       }

}输出的结果是

运行swap函数之前的a = 1 b= 2

在swap函数内部的a = 2 b= 1

运行了swap函数之后的a = 1 b= 2

由此可见,swap函数并未对main函数中的a和b互换值成功,但是a和b的数值又确实是传进了swap函数中;

看一下内存的过程

首先,main函数进栈,然后在栈中生成了a和b两个变量,,紧接着是将swap函数进栈,它也有个栈区,并且形参的值传入栈中,

 


                           

现在开始进行swap的函数执行,执行了swap方法之后,swap中的值变化,由此可见,swap中的值交换成功,但是main函数的值并没有改变,所以这个函数并不能完成交换值

 

 

那么如何完成这个交换呢?

public class testInt{

static int a = 1;

       static int b= 2;

 

       public staticvoid swap(){

              int temp= 0;

              temp = a;

              a = b;

              b = temp;

              System.out.println("在swap函数内部的a = " + a +" b="+b);

 

       }     

       public staticvoid main(String[] args){

             

              System.out.println("运行swap函数之前的a = " + a +" b="+b);

              swap();

              System.out.println("运行了swap函数之后的a = " + a +" b="+b);

       }

}

这样运行结果就变成了

运行swap函数之前的a = 1 b= 2

在swap函数内部的a = 2 b= 1

运行了swap函数之后的a = 2 b= 1

即交换成功.

 

第二种引用类型在方法中的值传递,这个是一个容易造成误解的值传递,但其实我们只要记住,Java中方法的参数传递方式只有一种值传递一种方式就好了.但是,引用类型究竟在内存中是怎样操作的呢?

例如:

//定义一个类来存放数据

class Data{

                int a;

                int b;

}

 

public class DataSwap {

                public static void swap(Datad){

                  int temp = d.a;

                  d.a = d.b;

                  d.b = temp;

                  System.out.println("在swap函数内部的a = " + d.a +" b="+d.b);

                }

                public static void main(String[]args){

                     Data data = new Data();

                     data.a = 1;

                     data.b = 2;

                     System.out.println("运行swap函数之前的a = " + data.a +" b="+data.b);

                     swap(data);

                     System.out.println("运行了swap函数之后的a = " + data.a +" b="+data.b);

                  }

 

}

运行结果是

运行swap函数之前的a = 1 b= 2

在swap函数内部的a = 2 b= 1

运行了swap函数之后的a = 2 b= 1

 

从结果看来,是交换成功了,这又是为什么呢?

看一下内存中发生了什么?

  


接下来,将d对象传给swap方法,如下图所示,也是将d的副本传给了swap函数;

 

 

如图所示,将d的副本传给swap,但是d的副本的值和d没有区别都是指向内存中相同的地址,所以swap的操作也是对原内存的操作,所以可以交换成功,如果我们将swap中的d赋值为null,这样的情况下,main栈区的d对象仍然可以访问到a,b的值,由此可见,swap的d和main中的d完全是两种不同的概率,并不影响.


原创粉丝点击