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

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

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

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

這雖然是一個(gè)老生常談的問(wèn)題,但是對(duì)于沒有深入研究過(guò)這塊,或者Java基礎(chǔ)不牢的同學(xué),還是很難回答得讓人滿意。

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

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

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

1. 什么是形參和實(shí)參

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

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

/**
* @author 一燈架構(gòu)
* @apiNote Java傳遞示例
**/
public class Demo {

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

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

}

在Java方法調(diào)用的過(guò)程中,就是把實(shí)參傳遞給形參,形參的作用域在方法內(nèi)部。

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

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

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

也就是說(shuō)值傳遞,傳遞的是副本。引用傳遞,傳遞的是實(shí)際內(nèi)存地址。這是兩者的本質(zhì)區(qū)別,下面會(huì)用到。

3. 測(cè)試驗(yàn)證

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

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

/**
* @author 一燈架構(gòu)
* @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);
}

}

輸出結(jié)果:

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

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

我們都知道Java基本數(shù)據(jù)類型是存儲(chǔ)在虛擬機(jī)棧內(nèi)存中,棧中存放著棧幀,方法調(diào)用的過(guò)程,就是棧幀在棧中入棧、出棧的過(guò)程。

當(dāng)執(zhí)行main方法的時(shí)候,就往虛擬機(jī)棧中壓入一個(gè)棧幀,棧幀中存儲(chǔ)的局部變量信息是count=0。

圖片

當(dāng)執(zhí)行update方法的時(shí)候,再往虛擬機(jī)棧中壓入一個(gè)棧幀,棧幀中存儲(chǔ)的局部變量信息是count=0。

圖片

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

3.2 引用類型驗(yàn)證

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

/**
* @author 一燈架構(gòu)
* @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);
}

}

輸出結(jié)果:

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

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

當(dāng)執(zhí)行main方法時(shí),會(huì)在堆內(nèi)存中開辟一塊內(nèi)存,在棧內(nèi)存中壓入一個(gè)棧幀,棧幀中存儲(chǔ)一個(gè)引用,指向堆內(nèi)存中的地址。

圖片

當(dāng)調(diào)用update方法時(shí),會(huì)把main方法的棧幀拷貝一份,再壓入棧內(nèi)存中,指向同一個(gè)堆內(nèi)存地址。

圖片

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

圖片

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

3.3 同一地址的引用類型驗(yàn)證

/**
* @author 一燈架構(gòu)
* @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);
}

}

輸出結(jié)果:

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

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

圖片

這是不是說(shuō)明Java支持引用傳遞呢?

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

4. 總結(jié)

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

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

當(dāng)傳參的引用類型,形參和實(shí)參指向同一個(gè)地址的時(shí)候,修改形參地址的內(nèi)容,會(huì)影響到實(shí)參。當(dāng)形參和實(shí)參指向不同的地址的時(shí)候,修改形參地址的內(nèi)容,并不會(huì)影響到實(shí)參。

責(zé)任編輯:武曉燕 來(lái)源: 一燈架構(gòu)
相關(guān)推薦

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ù)按值傳遞

2024-09-04 01:36:51

Java對(duì)象傳遞

2020-08-31 19:19:27

TCPUDP視屏面試

2018-10-09 15:26:19

JavaPython語(yǔ)言

2018-09-26 14:17:00

編程語(yǔ)言JavaPython

2009-08-17 14:48:44

Java參數(shù)傳遞機(jī)制

2015-04-21 09:20:40

SwfitObject—C

2018-03-26 10:00:40

2023-11-29 09:47:11

C++對(duì)象

2011-09-05 10:30:51

重構(gòu)代碼庫(kù)業(yè)務(wù)模型

2017-08-09 08:43:02

公有云趨勢(shì)聲勢(shì)

2024-03-28 13:13:00

Htmx前端開發(fā)框架

2012-12-27 11:11:54

華為任正非

2012-02-21 14:04:15

Java

2020-10-24 15:50:54

Java值傳遞代碼
點(diǎn)贊
收藏

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