Java中值传递的深度分析

  

  

首先说观点:java只有值传递没有引用传递

  

然后再来看看值传递与引用传递两者的定义

  

值传递(经过价值)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

  

引用传递(通过引用)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

  

这里牢记值传递中将。

  

然后就是对于参数类型:值类型和引用类型。

  

结合起来理解就是:值类型传递,java是将其值内容复制一份给形参,对于引用类型传递,java是将其一份给形参。

  

下面结合实例深入理解为什么java只有值传递

        包字符串;      公共类值传递{   公共静态void main (String [] args)   {   字符串str1=癮bc”;   updateStr1 (str1);   System.out.println(“主要函数中“+ str1);   }   公共静态孔隙updateStr1(字符串str1)   {   str1=癱ba”;//& lt;注解比;   System.out.println(“调用函数中“+ str1);   }      }      

结果:   

癑ava中值传递的深度分析"

  

在这里我们能够清晰看到我们传递的是字符串类型的对象即(引用类型),并且在调用函数中我们修改了str1为cba,如果是引用传递那么我们在主函数打印则应该是cba,

  

但是很遗憾我们在主函数中仍然打印出来的是abc,所以我们可以说java是值传递类型了吗,答案是不完全的。

  

接下来再看这一段代码:

        包字符串;         公共类人{私人int年龄;公共int getAge(){返回年龄;}公共空setAge (int年龄){。年龄=年龄;}      }   公共类值传递2 {   公共静态void main (String [] args)   {   人p1=new ();   p1.setAge (10);   System.out.println(“我在主函数里对p1的年龄属性赋值为“+ p1.getAge ());   setage (p1);   System.out.println(“我再从主函数里获取P1的年龄属性”+ p1.getAge ());   }      公共静态孔隙setage p1(人)   {   p1.setAge (18);//不是我们对它的地址进行了操作,而是我们对它地址的内容进行了操作   System.out.println(“我在调用函数里对p1的年龄属性重新赋值为“+ p1.getAge ());   }      }      

结果:   

癑ava中值传递的深度分析"

  

咦,怎么回事这次也是传递的对象(引用类型),为什么这次我们对年龄这个字段的修改在主函数同步了呢?

  

别急,下面我们先来分析这两个例子。

  

首先第一个类型的例子中,我们传递的是字符串类型的变量,它是一个特殊的类型的引用变量。

  

  

出于这句话的理解就是每个字符串都对应一个地址:我们例一中是将str1的地址复制给了我们的形参str1,并且形参中str1的地址进行了改变指向了“cba的地址。所以说在主函数中的str1的地址仍然指向的是“abc”所对应的地址。

  

所以说对于字符串类型的变量,我们对于给它重新赋值不是改变了它的内容,而是改变了它指向字符串的位置。这也就解释了为什么java类中字符串型是不可变类型。

  

而在我们例二中,我们将p1的地址给了我们形参中的p1,所以我们在调用函数对这个地址中的内容进行修改时就会同步到我们主函数中的p1。所以这个并不意味着这个是引用传递。

  

好吧,那怎么才能解释好Java确实是值传递呢(上字符串类面型例子是特殊的引用类型不方便解释)

  

下面我们通过这个例子说明:

        包字符串;   公共类人{   私人int年龄;   公共int getAge () {   返回年龄;   }   公共空间setAge (int年龄){   这一点。年龄=年龄;   }      }   公共类值传递3 {   公共静态void main (String [] args) {   人p1=new ();   人p2=new ();   p1.setAge (10);   p2.setAge (18);   System.out.println(“我在主函数里对p1的年龄属性赋值为“+ p1.getAge ());   System.out.println(“我在主函数里对p2的年龄属性赋值为“+ p2.getAge ());   交换(p1, p2);   System.out.println(“* * * * * * * * * * * *我是主函数里的分割线* * * * * * * * * * * * * * *”);//我再在主函数里分别对p1, p2获取他们的年龄,若为引用传递则p1的年龄应该为18,p2为10。   System.out.println(“我在主函数里获取p1的年龄”+ p1.getAge ());   System.out.println(“我在主函数里获取p1的年龄”+ p2.getAge ());   }   公共静态空间交换(人p1, p2)   {   System.out.println(“* * * * * * * * * * * *我是调用函数里的分割线* * * * * * * * * * * * * * *”);   人temp=new ();   temp=p1;   p1, p2;   p2=temp;   System.out.println(“我在调用函数里交换了p1和p2指向的地址”);   System.out.println(“我在调用函数里对p1的年龄属性赋值为“+ p1.getAge ());   System.out.println(“我在调用函数里对p2的年龄属性赋值为“+ p2.getAge ());      }      }

Java中值传递的深度分析