最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java中真的只有值傳遞么

 更新時間:2019年12月20日 10:07:57   作者:為何不是夢  
這篇文章主要介紹了淺談Java中真的只有值傳遞么?文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

回顧值傳遞和引用傳遞

關于Java是值傳遞還是引用傳遞,網上有不一樣的說法。

1、基本類型或基本類型的包裝類以及String是值傳遞,引用類型是引用傳遞。
2、Java中只有值傳遞。

關于這個問題應該是存在爭議的。根據測試出來的結果和我們自己的經驗,以及口口相傳或是上學時老師講的,我們認為是第一種。但第二種說法的呼聲也很高,漸漸地我們也認為第2中才是對的。那么下面我們就來分析一下這個問題。

在談這個問題之前我們先了解值傳遞和引用傳遞的概念及現(xiàn)象。我還記得,值傳遞和引用傳遞這些概念是大學里學Java的時候老師教給我的,它們的概念是什么呢?老師是通過例子來講解的,大概是這樣的。

值傳遞

例子1:

 public static void main(String[] args){
  TestJavaParamPass() tjpp = new TestJavaParamPass();
  int num = 10;
  tjpp.change(num);
  System.out.println("num in main():"+num);
 }
 public void change(int param){
  param = 20;
  System.out.println("param in change():"+param);
}

控制臺輸出:

param in change():20
num in main():10

mian()方法中的int變量num傳遞給change()方法,change()方法接收到后將值改變?yōu)?0。通過看控制臺輸出,main()方法中的num變量的值沒有改變。

結論:基本類型是值傳遞。

引用傳遞

例子2:

 public static void main(String[] args){
  TestJavaParamPass() tjpp = new TestJavaParamPass();
  User user = new User();
  user.setName("Jerry");
  tjpp.change(user);
  System.out.println("user in mian():"+user);
 }
 public void change(User param){
  param.setName("Tom");
 System.out.println("param in change():"+param);
}

控制臺輸出:

param in change():User(name=Tom}
user in mian():User(name=Tom}

main()方法中的user變量傳遞給change()方法,change()方法改變了其name屬性值。通過看控制臺輸出,main()方法中的user變量的name屬性值發(fā)生改變。

結論:引用類型是引用傳遞。

特殊的值傳遞

例子3:

 public static void main(String[] args){
  TestJavaParamPass() tjpp = new TestJavaParamPass();
  String name = "Jerry";
  tjpp.change(name);
  System.out.println("name in main():"+name);
 }
 public void change(String param){
  param = "Tom";
  System.out.println("param in change():"+param);
}

控制臺輸出:

param in change():Tom
name in mian():Jerry

String也是引用類型的數據類型,為什么值沒改變?因為在change()方法里param = "Tom";相當于param = new String("Tom");就相當于param被重新賦值指向了另外一個對象。所以,其實String類型傳的是引用,只不過被重新賦值指向了別的對象了,沒有修改原對象。即,String本質上還是引用傳遞,表像上是值傳遞。

結論:基本類型是值傳遞,引用類型是引用傳遞,String是特殊的值傳遞。

這個結論也是網絡上流傳的比較多的,可能大部分程序員的認知都是這樣的。至于值傳遞和引用傳遞的概念,接下來便可根據上面的例子和結論推斷出來,以及解釋為什么大多數程序員都將String理解為是特殊的值傳遞。

概念提取

與其叫概念提取好不如叫結論總結呢。

值傳遞:基本類型的變量在被傳遞給方法時,傳遞的是該變量的值(即復制自己的值傳遞給方法)。

引用傳遞:引用類型的變量在被傳遞給方法時, 傳遞的是該變量的引用(即自己所指向的內存地址)。

為什么說String是特殊的值傳遞:是因為String和基本類型從表象來說表現(xiàn)出來的結果是一樣,大概是為了便于記憶這個結果才這樣說的吧。但是要知道String也是引用傳遞只不過它的引用被重新賦值,指向了別的對象了,所以不會影響原值。所以String不能簡單的說是值傳遞。

解析Java只有值傳遞的說法

只有值傳遞的說法

網上還流傳一種說法叫Java只有值傳遞。網上有文章論證了Java只有值傳遞的說法,其中舉的例子和上面的類似。

分析的很透徹,解釋了上面三個例子的本質。指出了上面第二個例子的錯誤之處,舉的例子不恰當。并指出下面這樣的例子才恰當,又舉了鑰匙和房子的例子,佐證了上面第2個例子確實不恰當。因為上面的例子的側重點都是最后實際變量的值有沒有改變。

 public static void main(String[] args){
  TestJavaParamPass() tjpp = new TestJavaParamPass();
  User user = new User();
  user.setName("Jerry");
  tjpp.change(user);
  System.out.println("user in mian():"+user);
 }
 public void change(User param){
  param = new User()
 param.setName("Tom");
 System.out.println("param in change():"+param);
}

輸出:

param in change():User(name=Tom}
user in mian():User(name=Jerry}

最后文章的結論是Java只有值傳遞。引用類型大概是這樣解釋的( 基本類型就不用說了 ),實際變量(實際參數)賦值一份自己的引用地址的值傳給方法,方法的形式參數拿到的是實參的引用地址的值。側重點在值,所以結論說的是引用類型也是值傳遞。

解析

我覺得論證者分析基本類型和引用類型的實參形參的變化的原理是沒有問題的,但是得出的結論是不是有點不恰當。怎么說呢?請繼續(xù)看。

論證者的意思是,java只有值傳遞。也就是說引用類型也是值傳遞,側重點是復制一份引用的地址的值給形參,在于這里的值是引用的地址的值(不是引用所指向的內存里存的值),所以說是值傳遞。是不是有點牽強?我覺得有點偷換概念,沒錯,大家都知道引用類型傳遞的是引用的值,但你不能因為傳遞的是值就說是值傳遞,不傳值還能傳什么?引用是內存地址,不是也得用值表示么?

而傳統(tǒng)的說法:基本類型是值傳遞(內存里存東西所代表的值),引用類型是引用傳遞。我覺得這個側重點是:基本類型把值復制一份傳遞過去,引用類型把引用復制一份傳遞過去。側重點是傳遞的東西,基本類型傳遞的東西叫變量的值(變量本身所代表的值),引用類型傳遞的東西叫引用(引用本身的值,即內存地址),而非引用所指向的內存空間內的值。所以這樣理解引用類型傳遞的是引用也沒問題啊。

所以,Java中基本類型傳遞的是變量所代表的自身的值(內存里存東西所代表的值),是值傳遞;引用類型傳遞的是對象的引用,是引用傳遞;再深一步,引用也是一個確切的值來表示的,或者你把引用看作是對象的值,那也可以說引用類型傳遞的是對象的值,是值傳遞。

文章還說了

無論是值傳遞還是引用傳遞,其實都是一種求值策略(Evaluation strategy)。在求值策略中,還有一種叫做按共享傳遞(call by sharing)。其實Java中的參數傳遞嚴格意義上說應該是按共享傳遞。

按共享傳遞,是指在調用函數時,傳遞給函數的是實參的地址的拷貝(如果實參在棧中,則直接拷貝該值)。在函數內部對參數進行操作時,需要先拷貝的地址尋找到具體的值,再進行操作。如果該值在棧中,那么因為是直接拷貝的值,所以函數內部對參數進行操作不會對外部變量產生影響。如果原來拷貝的是原值在堆中的地址,那么需要先根據該地址找到堆中對應的位置,再進行操作。因為傳遞的是地址的拷貝所以函數內對值的操作對外部變量是可見的。

簡單點說,Java中的傳遞,是值傳遞,而這個值,實際上是對象的引用。

這里的意思是,不論是基本類型還是引用類型傳給函數的是實參的地址拷貝,也就是內存地址,可以說是引用,只不過基本類型在棧中,函數內對參數操作時直接拷貝的值,引用類型的值在堆中,需要先找到它的位置,即地址、引用。最后說java是值傳遞,而這個值是對象的引用。

看到這明白了么?

地址就是引用,那是不是可以說java是引用傳遞了?傳遞的是引用的值,計算機中不全是值嗎,不是值還能是什么,說是引用傳遞是側重點不同傳,傳過去的就是地址就是引用,引用不用值表示用啥

這里說的值不是一個概念,說基本類型傳的是值,這個是值變量本身的值,說對象傳的也是值,這個值說的是引用是地址,而說對象說是引用傳遞,側重點在于說是傳的地址,指向對象所代表的內部的屬性的地址,非對象所表示的內部的屬性的值,為的是和基本類型直接傳值區(qū)分開。

維基百科:引用 (程序設計)

在計算機科學中,引用(英語:reference)是指一個可以讓程序間接訪問于電腦存儲器或其他存儲設備中一特定數據的值,該數據可以為變量或記錄。
引用和數據本身不同。一般而言,引用會是數據存儲于存儲器或存儲設備中的物理地址。因此,引用亦常被稱為該數據的指針或地址。

看看引用的定義,引用是指一個XXX數據的值。好吧,引用本身就是一個值。但不是值還能是什么呢?計算機中不都是值么?

說值傳遞還是引用傳遞都沒有錯,關鍵是你怎么定義和解釋值傳遞、引用傳遞的概念以及值所表示的東西。

計算機中一切皆值,如果從這點出發(fā),那全都是傳的值啊,只不過細化到java中,基本類型傳遞的是自身的值,引用類型傳遞的是引用的值,而非對象內屬性的值。

所以如果武斷的說只有值傳遞也是沒問題的,因為在計算機中只能用值來表示啊,但覺得有點投機取巧,就和說世界上只有***,那還區(qū)分**和**干嘛,道理差不多。(暫時想不到好的例子哈哈)

還是剛才說的那句,說是引用傳遞,側重點在于說是傳的是引用是地址,而非對象所表示的內部的屬性值,為的是和基本類型直接傳值區(qū)分開,便于記憶.

最后

最后,大家理解現(xiàn)象的原理即可,沒必要追的那么深,或玩文字游戲,鉆牛角尖。

如果有人問你,你可以這么說,基本類型和他們的包裝類是值傳遞,引用類型傳遞的是對象的引用即地址值,String傳遞的也是地址值,只不過在函數內地址值被修改了,所以不會影響到實參,因表現(xiàn)上和基本類型一樣,所以可能為了便于記住這個現(xiàn)象才說String是值傳遞。歸根到底傳的都是值只不過值的含義不同。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Mybatis中Collection集合標簽的使用詳解

    Mybatis中Collection集合標簽的使用詳解

    這篇文章主要介紹了Mybatis中Collection集合標簽的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • java實現(xiàn)獲取安卓設備里已安裝的軟件包

    java實現(xiàn)獲取安卓設備里已安裝的軟件包

    本文給大家介紹的是如何獲取設備中已經安裝的應用軟件包的代碼,其核心方法原理很簡單,我們通過Android中提供的PackageManager類,來獲取手機中安裝的應用程序信息
    2015-10-10
  • Servlet 過濾器詳細介紹

    Servlet 過濾器詳細介紹

    這篇文章介紹了Servlet 過濾器,有需要的朋友可以參考一下
    2013-10-10
  • SpringBoot整合Echarts實現(xiàn)用戶人數和性別展示功能(詳細步驟)

    SpringBoot整合Echarts實現(xiàn)用戶人數和性別展示功能(詳細步驟)

    這篇文章主要介紹了SpringBoot整合Echarts實現(xiàn)用戶人數和性別展示,通過數據庫設計、實現(xiàn)數據訪問層、業(yè)務邏輯層和控制層的代碼編寫,以及前端頁面的開發(fā),本文詳細地介紹了SpringBoot整合Echarts的實現(xiàn)步驟和代碼,需要的朋友可以參考下
    2023-05-05
  • Java實現(xiàn)簡單的酒店管理系統(tǒng)

    Java實現(xiàn)簡單的酒店管理系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)酒店管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Java網絡編程之IO模型阻塞與非阻塞簡要分析

    Java網絡編程之IO模型阻塞與非阻塞簡要分析

    這篇文章主要介紹Java網絡編程中的IO模型阻塞與非阻塞簡要分析,文中附有示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • Spring AOP注解實戰(zhàn)指南

    Spring AOP注解實戰(zhàn)指南

    在現(xiàn)代軟件開發(fā)中,面向切面編程(AOP)是一種強大的編程范式,本文將介紹如何在Spring框架中通過AspectJ注解以及對應的XML配置來實現(xiàn)AOP,在不改變主業(yè)務邏輯的情況下增強應用程序的功能,需要的朋友可以參考下
    2024-06-06
  • Bean實例化之前修改BeanDefinition示例詳解

    Bean實例化之前修改BeanDefinition示例詳解

    這篇文章主要為大家介紹了Bean實例化之前修改BeanDefinition示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • java在linux本地執(zhí)行shell命令的實現(xiàn)方法

    java在linux本地執(zhí)行shell命令的實現(xiàn)方法

    本文主要介紹了java在linux本地執(zhí)行shell命令的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 詳解Spring Data Jpa 模糊查詢的正確用法

    詳解Spring Data Jpa 模糊查詢的正確用法

    本篇文章主要介紹了詳解Spring Data Jpa 模糊查詢的正確用法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論

桐乡市| 东丰县| 凤凰县| 沐川县| 双流县| 巴林右旗| 台安县| 博湖县| 辰溪县| 温泉县| 龙山县| 阿图什市| 内丘县| 建宁县| 宜宾县| 乌鲁木齐县| 阿拉善左旗| 栾城县| 交城县| 闽清县| 象山县| 习水县| 大新县| 兴业县| 临澧县| 东源县| 桐柏县| 东台市| 徐州市| 晋城| 昌都县| 西宁市| 利辛县| 汝阳县| 九龙城区| 嘉义县| 久治县| 监利县| 湘阴县| 敦煌市| 龙山县|