• 理解--->Java中的值传递&引用传递


    转自:http://url.cn/5tL9F5D

    值传递和引用传递

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

    引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数,形参和实参总是指向同一个地址,形参指向哪里实参就会指向哪里。

    java中的基本数据类型和引用数据类型

    java中的基本数据类型:
    • 4种整数类型:byte、short、int、long

    • 2种浮点数类型:float、double

    • 1种字符类型:char

    • 1种布尔类型:boolean

    java中的引用数据类型:
    • 接口

    • 数组

    下面就对JAVA中传递参数是值传递还是引用传递展开讨论

    下面先来看基本数据类型

    下面先来看基本数据类型

    public class Test {
        static void testInt(int a, int b)
        {
             a=10;
             b=20;
            System。out。println("交换后 "+"a:"+a+", b:"+b);
        }    
        public static void main(String[] args)
        {
            int a=1;
            int b=2;
            System。out。println("交换前 "+"a:"+a+", b:"+b);
            testInt(a,b);
            System。out。println("方法结束后"+"a:"+a+", b:"+b);
        } 
     }

    运行结果是这样的:

    交换前:1  2

    交换后:10  20

    res  :  1  2

    java中基本数据类型在传递的时候,用的是值传递,就是拷贝和实参一模一样的值然后由形参进行操作,当方法结束后,形参的生命周期就会终止,实参的值并没有受到影响。

    下面来看引用数据类型

    //  类的编写
      class Car
      {
      public String name;
           public Car()
           {}
           public Car(String name)
           {
           this。name=name;
           }
      }
    下面进行测试
    
    public class Test
    {
        public static void update1(Car car)
        {
          car。name="GTR";
          System。out。println("修改后的名字是:"+car。name);
        }
        //这个方法比上面的方法多了一条a=new Car()语句
        public static void update2(Car car)
        {
        car=new Car();
        car。name="GTR";
        System。out。println("修改后的名字是:"+car。name);
        }
        public static void main(String[] args)
        {
            Car a=new Car("AE86");
            Car b=new Car("AE86");
            System。out。println("调用update1前a的名字是:"+a。name);
            update1(a);
            System。out。println("调用update1后a的名字是:"+a。name);
            System。out。println("调用update2前b的名字是:"+b。name);
            update2(b);
            System。out。println("调用update2后b的名字是:"+b。name);
    
        }
    }

    结果:

    AE86

    GTR

    GTR

    AE86

    GTR

    AE86

    看完上面的update1方法,觉得引用数据类型和基本数据类型不一样,引用数据类型传入方法后,方法调用结束后对象的属性发生了变化,认为这是引用传递,将对象a的地址送到了形参中,然后对形参改变实参就会改变。

    但是update2马上就推翻了这个想法,将实参送入形参后,形参马上在堆中新建了一个对象,如果是引用传递,那么此时形参和实参都是指向这个对象的,然后程序又对形参的name属性进行了修改,那么此时实参也会被修改,看到的结果就应该和update1一样。但是结果却不是这样的,并没有修改数据,这就说明了将对象作为实参传入方法的形参,并不是引用传递。

    那么java中引用类型数据到底是怎么回事那,下面把自己的查阅资料理解的写下来。作为后续回顾。
    Car b = new Car(“AE86”);

    执行这个语句首先会在栈中创建一个b变量,然后在堆中创建一个Car类的实例,然后b指向堆中的实例。

    其实在java程序中,将对象传入形参中,也是值传递,基本数据类型值传递就是拷贝一个变量的副本;下面以update2()分析,引用数据类型就是将变量名(b)指向堆的地址复制一份,也就是说在栈中有一个变量名(car)也指向堆中b的实例。

    现在执行 car =new car();就是形参car指向了堆中一个新的地址,而b还是指向原来的地址的,这样的话,car随便修改name属性,是影响不到b的。最后方法结束car被释放,堆中的新对象被GC回收。

    在update1()中可以修改是因为形参和实参指向同一块内容,当形参修改name属性,那么堆中的对象就会被修改,update1()执行结束后,car释放,但堆中的实例还有变量指向,不会被回收,这时就修改了b的值。

  • 相关阅读:
    Https的请求过程
    计算机网络知识
    数据结构之图
    Python3线程池进程池
    数据结构之堆heapq
    EffectivePython并发及并行
    EffectivePython类与继承
    EffectivePython并发及并行
    5.19完全数
    5.18数字全排列
  • 原文地址:https://www.cnblogs.com/hahajava/p/10268403.html
Copyright © 2020-2023  润新知