Java中的按值传递与按引用传递到底是什么?

前  言

在进行Java开发相关工作的面试时,常常会出现下面这个问题:

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

*还有类似问题,如“简单谈谈按值传递与按引用传递”。

参考答案如下:

是值传递,因为Java编程语言中只有值传递参数。

当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

看着这个参考答案,好像懂了,却又总是感觉哪里不对,而对于这个问题,澳门网上真人博彩一直比较迷糊。但在看过网友“且听风吟”这篇《》分析文章后,就基本明白这个到底是怎么一回事了。主要原因还是欠缺对Java的内存机制的深刻理解,下面引用一下其文中分享的内容。

举例对比分析

1. 什么是按值传递

指的是在方法调用时,传递的参数是按值的拷贝传递。示例如下:

  1. public class TempTest {
  2.    private void test1(int a) {
  3.    //做点事情  
  4.    }
  5.    public static void main(String[] args) {
  6.       TempTest t = new TempTest();
  7.       int a = 3;
  8.       t.test1(a);//这里传递的参数a就是按值传递  
  9.    }
  10. }

按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。示例如下:

  1. public class TempTest {
  2.    private void test1(int a){
  3.       a = 5;
  4.       System.out.println("test1方法中的a="+a);
  5.    }
  6.    public static void main(String[] args) {
  7.       TempTest t = new TempTest();
  8.       int a = 3;
  9.       t.test1(a);//传递后,test1方法对变量值的改变不影响这里的a  
  10.       System.out.println(”main方法中的a=”+a);
  11.    }
  12. }

运行结果是:

  1. test1方法中的a=5
  2. main方法中的a=3

2. 什么是按引用传递

指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。示例如下:

  1. public class TempTest {
  2.    private void test1(A a){
  3.    }
  4.    public static void main(String[] args) {
  5.       TempTest t = new TempTest();
  6.       A a = new A();
  7.       t.test1(a); //这里传递的参数a就是按引用传递  
  8.    }
  9. }
  10. class A {
  11.    public int age = 0;
  12. }

3. 按引用传递的重要特点

传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。示例如下:

  1. public class TempTest {
  2.    private void test1(A a){
  3.       a.age = 20;
  4.       System.out.println("test1方法中的age="+a.age);
  5.    }
  6.    public static void main(String[] args) {
  7.       TempTest t = new TempTest();
  8.       A a = new A();
  9.       a.age = 10;
  10.       t.test1(a);
  11.       System.out.println(”main方法中的age=”+a.age);
  12.    }
  13. }
  14. class A{
  15.    public int age = 0;
  16. }

运行结果如下:

  1. test1方法中的age=20
  2. main方法中的age=20

*这里两个“a.age”的值相同的原因的是:只存在一个共同的“new A();”出来的内存空间,两个引用对象“a”指向的内容地址是相同,即两者操作的实际上就是同一个值。

4. 对上述例子的改变

理解了上面的例子,可能有人会问,那么能不能让按照引用传递的值,相互不影响呢?就是test1方法里面的修改不影响到main方法里面呢?

方法是在test1方法里面新new一个实例就可以了。改变成下面的例子,其中第3行为新加的:

  1.  public class TempTest {
  2.     private void test1(A a){
  3.     a = new A();//新加的一行  
  4.     a.age = 20;
  5.     System.out.println("test1方法中的age="+a.age);
  6.     }
  7.     public static void main(String[] args) {
  8.        TempTest t = new TempTest();
  9.        A a = new A();
  10.        a.age = 10;
  11.        t.test1(a);
  12.        System.out.println(”main方法中的age=”+a.age);
  13.     }
  14. }
  15. class A{
  16.     public int age = 0;
  17. }

运行结果为:

  1. test1方法中的age=20
  2. main方法中的age=10

*这里两个“a.age”的值不同的原因是:两个“new A();”并不是同一个内存空间,所以两个引用对象“a”所指向的地址也是不同的,可以说两者当前是互不影响的。

总  结

  • “在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。
  • 在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义字符串方式:String str = "Java私塾"; 。

您可以选择一种方式赞助本站

支付宝转账赞助

支付宝扫一扫赞助

发表评论