偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

死磕面試系列,Java到底是值傳遞還是引用傳遞?

開發(fā) 前端
當傳遞基本數(shù)據(jù)類型,比如原始類型(int、long、char等)、包裝類型(Integer、Long、String等),實參和形參都是存儲在不同的棧幀內,修改形參的棧幀數(shù)據(jù),不會影響實參的數(shù)據(jù)。

Java到底是值傳遞還是引用傳遞?

這雖然是一個老生常談的問題,但是對于沒有深入研究過這塊,或者Java基礎不牢的同學,還是很難回答得讓人滿意。

可能很多同學能夠很輕松的背出JVM、分布式事務、高并發(fā)、秒殺系統(tǒng)、領域模型等高難度問題,但是對于Java基礎問題不屑一顧。這種抓大放小的初衷是對的,要是碰到深究基礎細節(jié)的面試官,就抓瞎了。

今天一燈帶你一塊深入剖析Java傳遞的底層原理,看完這篇文章再去面試,面試官肯定要豎起大拇哥夸你:

“小伙子,你是懂Java傳遞的!”

1. 什么是形參和實參

形參: 就是形式參數(shù),用于定義方法的時候使用的參數(shù),是用來接收調用者傳遞的參數(shù)的。

實參: 就是實際參數(shù),用于調用時傳遞給方法的參數(shù)。實參在傳遞給別的方法之前是要被預先賦值的。

/**
* @author 一燈架構
* @apiNote Java傳遞示例
**/
public class Demo {

public static void main(String[] args){
String name = "一燈架構"; // 這里的name就是實際參數(shù)
update(name);
System.out.println(name);
}

// 這里方法參數(shù)列表中name就是形式參數(shù)
private static void update(String name){
// doSomething
}

}

在Java方法調用的過程中,就是把實參傳遞給形參,形參的作用域在方法內部。

2. 什么是值傳遞和引用傳遞

值傳遞: 是指在調用方法時,將實際參數(shù)拷貝一份傳遞給方法,這樣在方法中修改形式參數(shù)時,不會影響到實際參數(shù)。

引用傳遞: 也叫地址傳遞,是指在調用方法時,將實際參數(shù)的地址傳遞給方法,這樣在方法中對形式參數(shù)的修改,將影響到實際參數(shù)。

也就是說值傳遞,傳遞的是副本。引用傳遞,傳遞的是實際內存地址。這是兩者的本質區(qū)別,下面會用到。

3. 測試驗證

3.1 基本數(shù)據(jù)類型驗證

先用基本數(shù)據(jù)類型驗證一下:

/**
* @author 一燈架構
* @apiNote Java傳遞示例
**/
public class Demo {

public static void main(String[] args){
int count = 0;
update(count);
System.out.println("main方法中count:" + count);
}

private static void update(int count){
count++;
System.out.println("update方法中count:" + count);
}

}

輸出結果:

update方法中count:1
main方法中count:0

可以看到雖然update方法修改了形參count的值,但是main方法中實參count的值并沒有變,但是為什么沒有變?我們深究一下底層原理。

我們都知道Java基本數(shù)據(jù)類型是存儲在虛擬機棧內存中,棧中存放著棧幀,方法調用的過程,就是棧幀在棧中入棧、出棧的過程。

當執(zhí)行main方法的時候,就往虛擬機棧中壓入一個棧幀,棧幀中存儲的局部變量信息是count=0。

圖片

當執(zhí)行update方法的時候,再往虛擬機棧中壓入一個棧幀,棧幀中存儲的局部變量信息是count=0。

圖片

修改update棧幀中數(shù)據(jù),顯然不會影響到main方法棧幀的數(shù)據(jù)。

3.2 引用類型驗證

再用引用類型數(shù)據(jù)驗證一下:

/**
* @author 一燈架構
* @apiNote Java傳遞示例
**/
public class Demo {

public static void main(String[] args){
User user = new User();
user.setId(0);
update(user);
System.out.println("main方法中user:" + user);
}

private static void update(User user){
user = new User();
user.setId(1);
System.out.println("update方法中user:" + user);
}

}

輸出結果:

update方法中user:User(id=1)
main方法中user:User(id=0)

由代碼得知,update方法中重新初始化了user對象,并重新賦值,并不影響main方法中實參數(shù)據(jù)。

當執(zhí)行main方法時,會在堆內存中開辟一塊內存,在棧內存中壓入一個棧幀,棧幀中存儲一個引用,指向堆內存中的地址。

圖片

當調用update方法時,會把main方法的棧幀拷貝一份,再壓入棧內存中,指向同一個堆內存地址。

圖片

當執(zhí)行update方法,重新初始化user對象,并重新賦值的時候。會在堆內存中再開辟一塊內存,再把棧內存中update棧幀指向新的堆內存地址,并修改新的堆內存中的數(shù)據(jù)。

圖片

從這里可以看出是值傳遞,修改了形參里面數(shù)據(jù),實參并沒有跟著變化。

3.3 同一地址的引用類型驗證

/**
* @author 一燈架構
* @apiNote Java傳遞示例
**/
public class Demo {

public static void main(String[] args){
User user = new User();
user.setId(0);
update(user);
System.out.println("main方法中user:" + user);
}

private static void update(User user){
user.setId(1);
System.out.println("update方法中user:" + user);
}

}

輸出結果:

update方法中user:User(id=1)
main方法中user:User(id=1)

可以看出update方法修改user對象的屬性,main方法中user對象也跟著變了。

圖片

這是不是說明Java支持引用傳遞呢?

并不是。這里在參數(shù)傳遞的過程中,只是把實參的地址拷貝了一份傳遞給形參,update方法中只修改了參數(shù)地址里面的內容,并沒有對形參本身進行修改。

4. 總結

經過上述分析,Java參數(shù)傳遞中,不管傳遞的是基本數(shù)據(jù)類型還是引用類型,都是值傳遞。

當傳遞基本數(shù)據(jù)類型,比如原始類型(int、long、char等)、包裝類型(Integer、Long、String等),實參和形參都是存儲在不同的棧幀內,修改形參的棧幀數(shù)據(jù),不會影響實參的數(shù)據(jù)。

當傳參的引用類型,形參和實參指向同一個地址的時候,修改形參地址的內容,會影響到實參。當形參和實參指向不同的地址的時候,修改形參地址的內容,并不會影響到實參。

責任編輯:武曉燕 來源: 一燈架構
相關推薦

2020-09-02 08:00:51

Java引用傳遞值傳遞

2022-07-29 08:05:31

Java值傳遞

2023-11-15 09:14:27

Java值傳遞

2016-09-18 19:07:33

Java值傳遞引用傳遞

2021-03-06 09:18:51

JS閉包函數(shù)

2015-09-08 10:16:41

Java參數(shù)按值傳遞

2020-08-31 19:19:27

TCPUDP視屏面試

2024-09-04 01:36:51

Java對象傳遞

2018-10-09 15:26:19

JavaPython語言

2018-09-26 14:17:00

編程語言JavaPython

2015-04-21 09:20:40

SwfitObject—C

2009-08-17 14:48:44

Java參數(shù)傳遞機制

2018-03-26 10:00:40

2024-03-28 13:13:00

Htmx前端開發(fā)框架

2012-12-27 11:11:54

華為任正非

2023-11-29 09:47:11

C++對象

2017-08-09 08:43:02

公有云趨勢聲勢

2011-09-05 10:30:51

重構代碼庫業(yè)務模型

2012-02-21 14:04:15

Java

2014-11-17 10:03:23

OpenStack
點贊
收藏

51CTO技術棧公眾號