1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Java中的值傳遞和引用傳遞,看完這篇終于終于明白了!

        共 4624字,需瀏覽 10分鐘

         ·

        2020-10-17 01:52


        當(dāng)一個(gè)對(duì)象被當(dāng)作參數(shù)傳遞到一個(gè)方法后,此方法可改變這個(gè)對(duì)象的屬性,并可返回變化后的結(jié)果,那么這里到底是值傳遞還是引用傳遞??


        答:是值傳遞。Java 編程語(yǔ)言只有值傳遞參數(shù)。當(dāng)一個(gè)對(duì)象實(shí)例作為一個(gè)參數(shù)被傳遞到方法中時(shí),參數(shù)的值就是該對(duì)象的引用一個(gè)副本。指向同一個(gè)對(duì)象,對(duì)象的內(nèi)容可以在被調(diào)用的方法中改變,但對(duì)象的引用(不是引用的副本)是永遠(yuǎn)不會(huì)改變的。

        ? ? ??

        Java參數(shù),不管是原始類型還是引用類型,傳遞的都是副本(有另外一種說(shuō)法是傳值,但是說(shuō)傳副本更好理解吧,傳值通常是相對(duì)傳址而言)。

        ? ? ??

        如果參數(shù)類型是原始類型,那么傳過(guò)來(lái)的就是這個(gè)參數(shù)的一個(gè)副本,也就是這個(gè)原始參數(shù)的值,這個(gè)跟之前所談的傳值是一樣的。如果在函數(shù)中改變了副本的值不會(huì)改變?cè)嫉闹?。

        ? ? ??

        如果參數(shù)類型是引用類型,那么傳過(guò)來(lái)的就是這個(gè)引用參數(shù)的副本,這個(gè)副本存放的是參數(shù)的地址。如果在函數(shù)中沒(méi)有改變這個(gè)副本的地址,而是改變了地址中的值,那么在函數(shù)內(nèi)的改變會(huì)影響到傳入的參數(shù)。如果在函數(shù)中改變了副本的地址,如new一個(gè),那么副本就指向了一個(gè)新的地址,此時(shí)傳入的參數(shù)還是指向原來(lái)的 地址,所以不會(huì)改變參數(shù)的值。


        package?com.demo.test;

        public?class?Employee?{
        ????
        ????private?String name;
        ????private?double?salary;
        ????
        ????public?Employee(String name,double?salary){
        ????????this.name = name;
        ????????this.salary = salary;
        ????}

        ????public?String getName()?{
        ????????return?name;
        ????}

        ????public?void?setName(String name)?{
        ????????this.name = name;
        ????}

        ????public?double?getSalary()?{
        ????????return?salary;
        ????}

        ????public?void?setSalary(double?salary)?{
        ????????this.salary = salary;
        ????}
        }


        package com.demo.test;

        public?class?ParamTest?{

        ????public?static?void?main(String[] args) {
        ????????/**
        ?????????* Test 1: Methods can't modify numeric parameters
        ?????????*/

        ????????System.out.println("Testing tripleValue:");
        ????????double?percent = 10;
        ????????System.out.println("Before: percent="?+ percent);
        ????????tripleValue(percent);
        ????????System.out.println("After: percent="?+ percent);

        ????????/**
        ?????????* Test 2: Methods can change the state of object parameters
        ?????????*/

        ????????System.out.println("\nTesting tripleSalary:");
        ????????Employee harry = new?Employee("Harry", 50000);
        ????????System.out.println("Before: salary="?+ harry.getSalary());
        ????????tripleSalary(harry);
        ????????System.out.println("After: salary="?+ harry.getSalary());

        ????????/**
        ?????????* Test 3: Methods can't attach new objects to object parameters
        ?????????*/

        ????????System.out.println("\nTesting swap:");
        ????????Employee a = new?Employee("Alice", 70000);
        ????????Employee b = new?Employee("Bob", 60000);
        ????????System.out.println("Before: a="?+ a.getName());
        ????????System.out.println("Before: b="?+ b.getName());
        ????????swap(a, b);
        ????????System.out.println("After: a="?+ a.getName());
        ????????System.out.println("After: b="?+ b.getName());
        ????}

        ????private?static?void?swap(Employee x, Employee y) {
        ????????Employee temp = x;
        ????????x = y;
        ????????y = temp;
        ????????System.out.println("End of method: x="?+ x.getName());
        ????????System.out.println("End of method: y="?+ y.getName());
        ????}

        ????private?static?void?tripleSalary(Employee x) {
        ????????x.setSalary(x.getSalary()*3);
        ????????System.out.println("End of method: salary="?+ x.getSalary());
        ????}

        ????private?static?void?tripleValue(double?x) {
        ????????x = 3?* x;
        ????????System.out.println("End of Method X= "?+ x);
        ????}
        }


        運(yùn)行結(jié)果:


        Testing tripleValue:
        Before: percent=10.0
        End?of?Method X= 30.0
        After: percent=10.0

        Testing tripleSalary:
        Before: salary=50000.0
        End?of?method: salary=150000.0
        After: salary=150000.0

        Testing swap:
        Before: a=Alice
        Before: b=Bob
        End?of?method: x=Bob //可見(jiàn)引用的副本進(jìn)行了交換
        End?of?method: y=Alice
        After: a=Alice //引用本身沒(méi)有交換
        After: b=Bob


        首先要說(shuō)明的是java中是沒(méi)有指針的,java中只存在值傳遞,只存在值傳遞?。。?/strong> ?然而我們經(jīng)??吹綄?duì)于對(duì)象(數(shù)組,類,接口)的傳遞似乎有點(diǎn)像引用傳遞,可以改變對(duì)象中某個(gè)屬性的值。但是不要被這個(gè)假象所蒙蔽,實(shí)際上這個(gè)傳入函數(shù)的值是對(duì)象引用的拷貝,即傳遞的是引用的地址值,所以還是按值傳遞。


        示例1:


        public?class?Test?{

        ????public?static?void?change(int?a){
        ????????a=50;
        ????}

        ????public?static?void?main(String[] args) {
        ????????int?a=10;
        ????????System.out.println(a);
        ????????change(a);
        ????????System.out.println(a);
        ????}
        }


        很顯然輸出的 是10,10。傳遞的是值的一份拷貝,這份拷貝與原來(lái)的值沒(méi)什么關(guān)系。

        內(nèi)存分析:



        示例2:


        public?class?Test?{

        ????public?static?void?change(int?[]a){
        ????????a[0]=50;
        ????}

        ????public?static?void?main(String[] args) {
        ????????int?[]a={10,20};
        ????????System.out.println(a[0]);
        ????????change(a);
        ????????System.out.println(a[0]);
        ????}
        }


        顯然輸出結(jié)果為10 ? 50。實(shí)際傳遞的是引用的地址值。


        內(nèi)存分析:



        示例3:


        class?Emp?{
        ????public?int?age;
        }
        public?class?Test?{
        ????public?static?void?change(Emp emp)
        ????
        {
        ????????emp.age = 50;
        ????????emp = new?Emp();//再創(chuàng)建一個(gè)對(duì)象
        ????????emp.age=100;
        ????}
        ????
        ????public?static?void?main(String[] args) {
        ????????Emp emp = new?Emp();
        ????????emp.age = 100;
        ????????System.out.println(emp.age);
        ????????change(emp);
        ????????System.out.println(emp.age);
        ????????System.out.println(emp.age);
        ????}
        }


        輸出為:100 ?50 ?50.


        內(nèi)存分析:



        對(duì)于String類:


        public?class?Test?{
        ????public?static?void?change(String s){
        ????????s="zhangsan";
        ????}
        ????
        ????public?static?void?main(String[] args) {
        ????????String s=new?String("lisi");
        ????????System.out.println(s);
        ????????change(s);
        ????????System.out.println(s);
        ????}
        }


        輸出為:lisi ? lisi,由于String類是final修飾的,不可變,它會(huì)在內(nèi)存中在開辟一塊新空間。


        原文鏈接:cnblogs.com/xiaoxi/p/7400633.html


        瀏覽 33
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

          <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产又爽又色 | 国产高清不卡一区 | 在线一级片 | 免费a级黄片 | 一级片视频免费观看 | 肉感大码丰满小向美奈子 | 在线播放 神尾舞视频 | 欧美日韩一区在线观看 | h喷水荡肉失禁爽高h在线观看 | 国产精品国产三级国产传播 |