自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官:Java為什么只有值傳遞?

開發(fā) 后端
面試官愛問的一個(gè)基礎(chǔ)問題:Java是值傳遞還是引用傳遞?今天咱們就來好好分析一波。

[[348167]]

面試官愛問的一個(gè)基礎(chǔ)問題:Java是值傳遞還是引用傳遞?

想必大家都對(duì)這個(gè)問題都有自己的看法,那到底事實(shí)是怎樣的,我們又該如何回答面試官這個(gè)問題呢?今天咱們就來好好分析一波

值傳遞?引用傳遞?

首先,我們得先知道什么叫值傳遞,什么叫引用傳遞,知道這個(gè)才能理解Java到底如何做的。若想理解這兩種傳遞需要先理解形式參數(shù)和實(shí)際參數(shù)兩個(gè)概念

形式參數(shù):定義函數(shù)時(shí)使用的參數(shù),用來接收函數(shù)傳入?yún)?shù),比如我們寫個(gè)函數(shù),函數(shù)中的參數(shù)為形式參數(shù) 

  1. public void test(String str) { //str為形式參數(shù)  
  2.     System.out.println(str);  

實(shí)際參數(shù):我們調(diào)用函數(shù)時(shí),函數(shù)名后面括號(hào)中的參數(shù)稱為實(shí)際參數(shù),如下面例子所示 

  1. public static void main(String[] args) {  
  2.     A a = new A();  
  3.     a.test("chengxukong");//chengxukong則為實(shí)際參數(shù)  

可以發(fā)現(xiàn),當(dāng)調(diào)用一個(gè)有參函數(shù)的時(shí)候,會(huì)把實(shí)際參數(shù)傳遞給形式參數(shù);于是這個(gè)傳遞的過程便有兩種情況,即值傳遞和引用傳遞

值傳遞就是把參數(shù)的值給你,調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣函數(shù)內(nèi)部對(duì)參數(shù)內(nèi)部進(jìn)行修改不會(huì)影響到實(shí)際參數(shù);而引用傳遞就不一樣了,它直接把參數(shù)的實(shí)際地址給調(diào)用函數(shù)了,函數(shù)內(nèi)部可直接修改該地址內(nèi)容,會(huì)影響到實(shí)際參數(shù)

我來舉個(gè)例子,我司有一個(gè)數(shù)據(jù)庫A,僅允許內(nèi)部人員操作,現(xiàn)在有個(gè)項(xiàng)目需要和別的公司合作,該數(shù)據(jù)庫的數(shù)據(jù)需要交給合作公司一份,我總不能直接把我司數(shù)據(jù)庫A地址給他們,讓他們直接連我們數(shù)據(jù)庫A吧,他們要是刪庫跑路了,那我boss豈不要?dú)⑽壹捞炝?/p>

所以這個(gè)時(shí)候,把我司數(shù)據(jù)庫表數(shù)據(jù)拷貝一份到一個(gè)新的數(shù)據(jù)庫B,合作公司可以看這個(gè)數(shù)據(jù)庫B數(shù)據(jù),他們也可以隨意操作,不會(huì)影響我司數(shù)據(jù)庫

這個(gè)操作就類似于值傳遞,如果合作公司直接操作我司數(shù)據(jù)庫,就類似于引用傳遞了,這下大家應(yīng)該曉得兩者之別了

Java值傳遞還是引用傳遞?

我們了解了值傳遞和引用傳遞的概念,那Java中到底是哪種傳遞方式呢?我們來看代碼分析 

  1. public static void main(String[] args) {  
  2.     Fans fans = new Fans();  
  3.     int t = 1 
  4.     fans.test(t);  
  5.     System.out.println("In main:" + t);  
  6.  }  
  7.  public void test(int t) {  
  8.     t = 2 
  9.     System.out.println("In test:" + t);  
  10.  }  
  11. //輸出  
  12. In test:2  
  13. In main:1 

上述代碼,在main中定義t的值是1,在函數(shù)test中修改了參數(shù)t的值為2,這個(gè)結(jié)果是不是很容易分析出來了呢?test函數(shù)并未改變傳入的t的值,那按照上面我們的介紹是不是可以得出結(jié)論:Java中是值傳遞

有的人可能會(huì)質(zhì)疑,你傳入的參數(shù)t是基本類型,你若傳入引用對(duì)象類型,那肯定就會(huì)改變對(duì)象內(nèi)容了,OK,再來看一段引用類型代碼 

  1. int a = 10 
  2. String b = "fans" 
  3. public void test(Fans fans) {  
  4.     fans.a = 20 
  5.     fans.b = "newFans" 
  6.     System.out.println("In test,A:" + fans.a+",B:"+fans.b);  
  7.  
  8. public static void main(String[] args) {  
  9.     Fans fa = new Fans();  
  10.     fa.test(fa);  
  11.     System.out.println("In main,A:" + fans.getA()+",B:"+fans.getB()); 
  12.  
  13. //輸出  
  14. In test,A:20,B:newFans  
  15. In main,A:20,B:newFans 

哎啊,輸出結(jié)果竟然一樣了,也就是傳入的fans對(duì)象被函數(shù)test修改了,那這樣是不是又變成了引用傳遞了?

于是得出結(jié)論,基本類型是值傳遞,引用類型是引用傳遞?事實(shí)是這個(gè)樣子嗎,我們?cè)賮硗ㄟ^String這個(gè)引用類型實(shí)驗(yàn)下 

  1. public void test(String t) {  
  2.     t = "BBB" 
  3.     System.out.println("In test:" + t);  
  4.  
  5. public static void main(String[] args) {  
  6.     Fans fans = new Fans();  
  7.     String tt = "AAA"
  8.      fans.test(tt);  
  9.     System.out.println("In main:" + t);  
  10.  
  11. //輸出  
  12. In test:BBB  
  13. In main:AAA 

啊,這,咋肥事,傳遞的參數(shù)值并未修改,怎么又變成值傳遞了

上述三個(gè)例子表現(xiàn)結(jié)果各有差異,到底結(jié)論是什么呢?一起來分析下

第一個(gè)傳入的是基本類型,基本類型指向的就是數(shù)值,傳遞類似于賦值操作,不會(huì)對(duì)原數(shù)值產(chǎn)生影響,就是類似于a=10,b=a,b=20這種,并不會(huì)使a變?yōu)?0;

第二個(gè)引用對(duì)象傳入的是引用類型fans的地址的值,傳入的原參數(shù)fa指向地址0x123456,所以函數(shù)test的參數(shù)fans也指向0x123456,函數(shù)內(nèi)部對(duì)引用fans進(jìn)行修改,于是修改了0x123456地址的值,造成外部改變

第三個(gè)引用對(duì)象是String類型,同樣傳入的是原參數(shù)tt的指向地址0x123456,函數(shù)test參數(shù)t也是指向0x123456的值,那為什么這個(gè)和第二個(gè)結(jié)果不一樣的嘞?重點(diǎn)在于 t="BBB"; 這一句本來想嘗試著使內(nèi)容"AAA"改變成"BBB",但是無奈,String類型是static final類型的,這個(gè)大家應(yīng)該曉得的不,不曉得的該去補(bǔ)課讀讀String的源碼了,于是變成了 t=new String("BBB"),t指向了另一個(gè)地址,這個(gè)地址的內(nèi)容是"BBB",所以原來的引用tt還是指向原來的地址0x123456,并未改變

有的同學(xué)可能會(huì)提出問題了,為什么第二個(gè)可以改變這個(gè)地址的內(nèi)容,第三個(gè)不行?很明顯啊,String是final的,不可修改,而第二個(gè)可以直接修改該地址的內(nèi)容;那問題又來了,既然這樣,還能叫值傳遞嗎?

告訴你,就是值傳遞,因?yàn)槲覀兊诙€(gè)的驗(yàn)證方法不對(duì),你如果在函數(shù)的第一行加上個(gè)fans = new Fans();你看看它還輸出啥,這就變成和第三個(gè)String類似的道理了,改變了函數(shù)參數(shù)的指向位置,函數(shù)外部和函數(shù)內(nèi)部輸出就不一樣了,函數(shù)內(nèi)部也就不會(huì)影響外部了;如果按照應(yīng)引用傳遞,即使加了這一句,也應(yīng)該是函數(shù)內(nèi)外都是輸出一樣的,況且,這也有悖于引用傳遞的會(huì)改變傳入?yún)?shù)的概念

思考

值傳遞和引用傳遞并不是按照傳遞的內(nèi)容來區(qū)分的,傳遞的是引用的并不一定的引用傳遞,根據(jù)定義結(jié)果來區(qū)分;

在Java中用的是值傳遞(記好咯,下次面試別回答錯(cuò)了)

在其它方法里面改變引用類型的值都是通過引用改變的,當(dāng)傳遞引用對(duì)象的時(shí)候,傳遞的是復(fù)制的引用的對(duì)象句柄,是復(fù)制過的,也就是在內(nèi)存中復(fù)制了一個(gè)句柄,這兩個(gè)句柄指向同一個(gè)對(duì)象,所以你改變這個(gè)句柄對(duì)應(yīng)的空間的數(shù)據(jù)會(huì)影響到外部的變量 。

 

責(zé)任編輯:龐桂玉 來源: Hollis
相關(guān)推薦

2023-11-15 09:14:27

Java值傳遞

2022-07-06 13:48:24

RedisSentinel機(jī)制

2023-12-06 09:10:28

JWT微服務(wù)

2021-02-19 10:02:57

HTTPSJava安全

2021-01-21 07:53:29

面試官Promis打印e

2021-09-07 10:44:33

Java 注解開發(fā)

2021-12-20 10:30:33

forforEach前端

2024-02-22 15:36:23

Java內(nèi)存模型線程

2023-12-20 14:35:37

Java虛擬線程

2022-12-27 08:39:54

MySQL主鍵索引

2023-07-05 08:17:38

JDK動(dòng)態(tài)代理接口

2022-12-22 14:32:37

JavaScript編程語言

2023-06-05 07:57:53

Kafka消息事務(wù)消息

2012-02-21 14:04:15

Java

2020-08-24 10:55:41

數(shù)據(jù)庫雙寫代碼

2020-12-23 13:29:15

微服務(wù)架構(gòu)面試官

2023-11-30 08:16:19

SpringjarTomcat

2024-01-11 08:12:20

重量級(jí)監(jiān)視器

2024-11-21 10:38:10

2021-11-15 09:32:06

浮點(diǎn)面試Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)