亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java方法的參數(shù)傳遞機(jī)制詳解

 更新時間:2024年01月02日 10:36:01   作者:luffylv  
這篇文章主要介紹了Java方法的參數(shù)傳遞機(jī)制詳解,對于Java初學(xué)者來說,剛學(xué)習(xí)Java的時候可能經(jīng)常會聽到調(diào)用方法時參數(shù)的值傳遞與引用傳遞,但是,實際上Java中方法的參數(shù)傳遞機(jī)制只有值傳遞,需要的朋友可以參考下

前言

對于Java初學(xué)者來說,剛學(xué)習(xí)Java的時候可能經(jīng)常會聽到調(diào)用方法時參數(shù)的值傳遞與引用傳遞。

但是,實際上Java中方法的參數(shù)傳遞機(jī)制只有值傳遞。 首先,我們要了解一個概念——棧幀。

棧幀位于java虛擬機(jī)棧中,用于支持虛擬機(jī)進(jìn)行方法的調(diào)用和方法的執(zhí)行??梢院唵蔚睦斫鉃闂捶椒ā?/p>

每個方法有自己獨立的棧幀。棧幀中有局部變量表、操作數(shù)棧、動態(tài)鏈接、返回地址等。

下面我們通過幾個例子具體分析java方法的參數(shù)傳遞機(jī)制。

方法的參數(shù)為基本數(shù)據(jù)類型

首先我們來看下面代碼:

public class ParamTransmit {
    public static void main(String[] args) {
        int i = 1;
        change(i);
        System.out.println("i = " + i);
    }
    public static void change(int j) {
        j += 1;
    }
}

程序的運(yùn)行結(jié)果為:

在這里插入圖片描述

當(dāng)在main方法中調(diào)用change方法時,參數(shù)傳遞相當(dāng)于將main棧幀中的參數(shù)i=1拷貝了一份給change棧幀,此時change棧幀中,變量j的值為1。然后在change方法中執(zhí)行j += 1;運(yùn)算,j的值變?yōu)?,change方法結(jié)束。main方法未結(jié)束,此時main棧幀中變量i的值仍為1。當(dāng)傳遞的參數(shù)是基本數(shù)據(jù)類型時,傳遞的是數(shù)據(jù)值,即將參數(shù)拷貝一份到被調(diào)用方法的棧幀中。該方法中對變量的操作不影響原來棧幀中的變量的值,原棧幀中的變量不被修改。

在這里插入圖片描述

方法的參數(shù)為引用類型

引用類型變量如String類型,包裝類,數(shù)組和其他自定義類等。下面依次介紹。

String類型

先上代碼

public class ParamTransmit {
    public static void main(String[] args) {
        String str = "hello";
        change(str);
        System.out.println("str = " + str);
    }
    public static void change(String str) {
        str += "world";
    }
}

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

在這里插入圖片描述

首先,在jdk1.7之后,運(yùn)行時常量池從方法區(qū)中移了出來,在堆中開辟了一塊區(qū)域存放運(yùn)行時常量。

并且要知道String的值是不可變的,每次對String的操作都會產(chǎn)生新的String對象。

因此,在上面代碼中,main方法中調(diào)用change方法時,首先是將變量str的值(即運(yùn)行時常量池中hello的地址)拷貝一份到change棧幀中,此時change棧幀中的變量str也是指向“hello”。

然后執(zhí)行str += "world";操作,由于String值不可變,此時change棧幀中的str指向新的字符串“helloworld”,str的地址值已改變。

而此時main棧幀中str的值并沒有改變,仍指向“hello”,所以main方法中輸出的str仍是“hello”。

在這里插入圖片描述

包裝類

先上代碼:

public class ParamTransmit {
    public static void main(String[] args) {
        Integer num = 200;
        change( num);
        System.out.println("num = " + num);
    }
    private static void change(Integer num) {
        num += 1;
    }
}

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

在這里插入圖片描述

上面代碼中,首先Integer num = 200;會自動裝箱,先調(diào)用Integer.valueOf(200),在堆中創(chuàng)建一個值為200的Integer實例,并將該實例的地址賦值給num。

main方法在調(diào)用change方式時傳遞的是num的地址值,此時change棧幀中的num也指向值為200的Integer實例。

當(dāng)執(zhí)行num += 1;時,也自動裝箱,先調(diào)用Integer.valueOf(201),在堆中創(chuàng)建一個職位201的Integer實例,并將該實例的地址賦值給change棧幀中的變量num,change方法結(jié)束。

但此時,main棧幀的num仍指向值為200的Integer實例,因此打印結(jié)果為200。

內(nèi)存結(jié)構(gòu)圖如下:

在這里插入圖片描述

注:上述內(nèi)存結(jié)構(gòu)圖僅適用于不在-128至127之間的整數(shù)。Integer類的自動裝箱機(jī)制是首先提供一個Integer cache[],用于存放-128至127的緩存。因此,若對實參及對形參操作的結(jié)果均在-128至127之間,則實參及形參應(yīng)指向數(shù)組中的元素,而不是堆中新的Integer實例。

數(shù)組

直接上代碼

import java.util.Arrays;
public class ParamTransmit {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        change(arr);
        System.out.println("arr = " + Arrays.toString(arr));
    }
    private static void change(int[] arr) {
        arr[0] += 1;
    }

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

在這里插入圖片描述

數(shù)組變量也是引用類型。main方法在調(diào)用change方法時,傳遞的是數(shù)組arr的地址值。

change方法內(nèi),將數(shù)組中第一個元素的值自增1,此時數(shù)組中第一個元素的值變?yōu)?。

change方法結(jié)束,main方法繼續(xù)執(zhí)行,此時main棧幀變量arr仍指向該數(shù)組,只不過該數(shù)組中的元素已被修改。所以輸出的是被修改后的數(shù)組。

內(nèi)存結(jié)構(gòu)示意圖如下:

在這里插入圖片描述

可以引申為多維數(shù)組及數(shù)組元素為引用類型的情況。

其他自定義類

直接上代碼

class MyData {
    int a = 10;
}
public class ParamTransmit {
    public static void main(String[] args) {
        MyData md = new MyData();
        change(md);
        System.out.println("md.a = " + md.a);
    }
    private static void change(MyData md) {
        md.a += 1;
    }
}

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

在這里插入圖片描述

main方法調(diào)用change方法時,同樣是將main棧幀中的變量md的值傳遞到change棧幀中,此時傳遞的是地址值,指向堆中同一個MyData實例。

然后執(zhí)行md.a += 1,此時該實例的成員變量a為11。

change方法執(zhí)行完畢,main方法未結(jié)束,main棧幀中的變量md仍指向該實例,此時輸出的a為11。內(nèi)存結(jié)構(gòu)如下圖。

在這里插入圖片描述

若將上面代碼修改如下,會是什么結(jié)果呢?

class MyData {
    int a = 10;
}
public class ParamTransmit {
    public static void main(String[] args) {
        MyData md = new MyData();
        change(md);
        System.out.println("md.a = " + md.a);
    }
    private static void change(MyData md) {
        md = new MyData();
        md.a += 1;
    }
}

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

在這里插入圖片描述

main方法調(diào)用change方法時,同樣傳遞的是地址值。

然而執(zhí)行md = new MyData();時,在堆中創(chuàng)建了一個新的實例。

此時change棧幀中的變量md的值變成了新的MyData實例的地址。

然后繼續(xù)執(zhí)行md.a += 1;,修改的是新的實例的成員變量。

當(dāng)change方法調(diào)用結(jié)束后,main方法繼續(xù)執(zhí)行,此時main棧幀中md指向的仍是原來的實例,原實例的成員變量未被修改,仍是10。因此輸出結(jié)果是10。

內(nèi)存結(jié)構(gòu)如下圖。

在這里插入圖片描述

總結(jié)

通過以上分析,我們可以知道java的參數(shù)傳遞機(jī)制是值傳遞。

若參數(shù)是基本數(shù)據(jù)類型,傳遞的是數(shù)據(jù)值;若參數(shù)是引用數(shù)據(jù)類型,傳遞的是地址值。

若參數(shù)是基本數(shù)據(jù)類型,對形參的操作不影響實參,因其是不同棧幀的不同變量。

若參數(shù)是引用數(shù)據(jù)類型,并且是String、包裝類等。

因其對象的不可變性,對形參的操作會導(dǎo)致其指向新的String或包裝類等對象,但不影響實參,實參仍指向原來的對象且該對象并未被修改。

若參數(shù)是引用數(shù)據(jù)類型,并且是數(shù)組、StringBuffer及其他自定義類等時,對形參的操作會影響到實參,因其指向的是同一個實例。

到此這篇關(guān)于Java方法的參數(shù)傳遞機(jī)制詳解的文章就介紹到這了,更多相關(guān)Java方法的參數(shù)傳遞內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IDEA上實現(xiàn)JDBC編程的方法步驟

    IDEA上實現(xiàn)JDBC編程的方法步驟

    本文主要介紹了IDEA上實現(xiàn)JDBC編程的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java+Mysql學(xué)生管理系統(tǒng)源碼

    Java+Mysql學(xué)生管理系統(tǒng)源碼

    這篇文章主要為大家詳細(xì)介紹了Java+Mysql學(xué)生管理系統(tǒng)源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • maven三個常用的插件使用介紹

    maven三個常用的插件使用介紹

    大家好,本篇文章主要講的是maven三個常用的插件使用介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • java實現(xiàn)微信企業(yè)付款到個人

    java實現(xiàn)微信企業(yè)付款到個人

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)微信企業(yè)付款到個人功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Java中String.format的使用方法總結(jié)

    Java中String.format的使用方法總結(jié)

    這篇文章主要介紹了Java中String.format的用法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • java多線程編程必備volatile與synchronized深入理解

    java多線程編程必備volatile與synchronized深入理解

    這篇文章主要介紹了java多線程編程必備volatile與synchronized的深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • java 引用類型的數(shù)據(jù)傳遞的是內(nèi)存地址實例

    java 引用類型的數(shù)據(jù)傳遞的是內(nèi)存地址實例

    這篇文章主要介紹了java 引用類型的數(shù)據(jù)傳遞的是內(nèi)存地址實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java接口繼承和使用接口操作示例

    Java接口繼承和使用接口操作示例

    這篇文章主要介紹了Java接口繼承和使用接口操作,結(jié)合具體實例形式分析了Java接口繼承與使用的相關(guān)原理、操作技巧與注意事項,需要的朋友可以參考下
    2019-09-09
  • Java實現(xiàn)瀏覽器大文件上傳的示例詳解

    Java實現(xiàn)瀏覽器大文件上傳的示例詳解

    文件上傳是許多項目都有的功能,用戶上傳小文件速度一般都很快,但如果是大文件幾個g,幾十個g的時候,上傳了半天,馬上就要完成的時候,網(wǎng)絡(luò)波動一下,文件又要重新上傳,所以本文給大家介紹了Java實現(xiàn)瀏覽器大文件上傳的示例,需要的朋友可以參考下
    2024-07-07
  • IntelliJ IDEA連接MySQL數(shù)據(jù)庫詳細(xì)圖解

    IntelliJ IDEA連接MySQL數(shù)據(jù)庫詳細(xì)圖解

    今天小編就為大家分享一篇關(guān)于intellij idea連接mysql數(shù)據(jù)庫詳細(xì)圖解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10

最新評論