java通過方法來交換實(shí)參的值實(shí)現(xiàn)方式
一、代碼實(shí)例引出

代碼輸出結(jié)果:

我們可以看到,盡管我們寫了一個(gè)交換方法來交換a與b的值,但是從結(jié)果來看好像沒有發(fā)生交換,這是為什么?如何修改才能使其發(fā)生交換?有幾種方法能夠做到?這就是今天要做的事情
二、為什么無法發(fā)生交換?
答:在java中,方法參數(shù)的傳遞方式是值傳遞(pass by value),這意味著當(dāng)你將變量傳遞給方法的時(shí)候,實(shí)際上傳遞的是變量的副本,而不是變量本身
在上述代碼中,swap方法接受兩個(gè)int類型的參數(shù)x和y.當(dāng)你在main方式中調(diào)用swap(a,b)時(shí),java會(huì)將a和b分別復(fù)制一份傳遞給x和y
在swap的方法內(nèi)部,x和y的值確實(shí)被交換了.但這只是交換了x和y的副本值,而不是main方法中a和b的值.當(dāng)swap方法執(zhí)行完畢后,x和y的生命周期結(jié)束,他們的值不會(huì)影響到main方法中的a和b
因此main方法中的a和b的值沒有呢發(fā)生交換,輸出的結(jié)果仍然是交換前的值
三、如何修改能使其發(fā)生交換?
方法 1:用數(shù)組封裝(利用引用傳遞特性)
基本類型本身無法直接通過方法修改外部變量,但可以用數(shù)組(引用類型)封裝,通過修改數(shù)組元素實(shí)現(xiàn)交換:

方法 2:用Integer不行?注意!
雖然 Integer 是引用類型,但由于 Integer 內(nèi)部值是 final 修飾的(不可變) ,直接傳遞 Integer 對(duì)象也無法真正交換。
若想模擬,需自定義一個(gè) “可變” 的包裝類(或用 Java 提供的 AtomicInteger 等,不過更推薦簡(jiǎn)單場(chǎng)景用數(shù)組)。
比如自定義一個(gè)簡(jiǎn)單的可變包裝類:

方法 3:返回交換后的結(jié)果(無需修改外部變量,直接返回新值)
如果不想用數(shù)組或自定義類,也可以讓 swap 返回交換后的結(jié)果數(shù)組 / 對(duì)象,重新接收賦值:

總結(jié):最簡(jiǎn)潔的方式是用數(shù)組封裝基本類型(方法 1),利用引用傳遞修改內(nèi)部元素;若追求更面向?qū)ο?,可自定義可變包裝類(方法 2);簡(jiǎn)單場(chǎng)景也可直接返回交換結(jié)果(方法 3)。
當(dāng)然也可以這樣改

當(dāng)然如果要賦值這樣還不夠,需要增加一個(gè)構(gòu)造方法來初始化value的值



至于這一塊為什么要加static,這就涉及到了之前的模塊,內(nèi)部類.
我們來回顧一下:
四、回顧:內(nèi)部類
在 Java 中,static class MyValue 這里的 static 是用來修飾內(nèi)部類的,它的作用和報(bào)錯(cuò)原因與 Java 的類加載、內(nèi)部類訪問規(guī)則有關(guān),具體可以這么理解:
1. 內(nèi)部類的“歸屬”問題
- 我們寫的
MyValue是定義在另一個(gè)類(假設(shè)是Main類,因?yàn)橛?nbsp;main方法)里面的內(nèi)部類。 - 內(nèi)部類默認(rèn)是 “依賴外部類對(duì)象” 存在的(非靜態(tài)內(nèi)部類),它需要先有外部類的實(shí)例,才能創(chuàng)建自己的實(shí)例。(也就是說,如果把不加static,將這段代碼放到外面,這串代碼也是正確的)

- 但你的
main方法是static的(靜態(tài)方法),靜態(tài)方法里不能直接創(chuàng)建 “非靜態(tài)內(nèi)部類” 的對(duì)象 ,因?yàn)殪o態(tài)方法不依賴外部類實(shí)例,而非靜態(tài)內(nèi)部類卻依賴,兩者矛盾。
2. static修飾內(nèi)部類的作用
給內(nèi)部類加上 static 后,它就變成了靜態(tài)內(nèi)部類:
- 靜態(tài)內(nèi)部類不再依賴外部類的實(shí)例,”相當(dāng)于和外部類 “平級(jí),可以直接在靜態(tài)方法(比如
main)里創(chuàng)建對(duì)象。 - 簡(jiǎn)單說:
static讓內(nèi)部類脫離了 “必須依附外部類對(duì)象” 的限制,能在靜態(tài)環(huán)境(如main)里直接用。
3. 不加static會(huì)報(bào)錯(cuò)的場(chǎng)景
如果去掉 static,MyValue 就是非靜態(tài)內(nèi)部類,此時(shí)在 main(靜態(tài)方法)里寫 new MyValue() 就會(huì)報(bào)錯(cuò),因?yàn)椋?/p>
- 靜態(tài)方法
main執(zhí)行時(shí),可能還沒有外部類的實(shí)例。 - 非靜態(tài)內(nèi)部類需要外部類實(shí)例才能創(chuàng)建,Java 不允許這種 “無依賴創(chuàng)建”,所以會(huì)提示類似 “無法從靜態(tài)上下文引用非靜態(tài)內(nèi)部類” 的錯(cuò)誤。
總結(jié)一下:
- 加
static是為了把內(nèi)部類變成靜態(tài)內(nèi)部類,讓它可以在靜態(tài)方法(比如main)里直接使用 。如果不加static,非靜態(tài)內(nèi)部類依賴外部類實(shí)例,而靜態(tài)方法里沒法保證有外部類實(shí)例,就會(huì)報(bào)錯(cuò)~ - 那么這時(shí)候就有聰明的小豬要問了,"同學(xué)同學(xué),那我把static全都刪掉不就好了"
- 很遺憾的說,這樣是不行的
4. 為什么不能把static全部去掉
如果把全部的 static 都去掉,代碼會(huì)無法編譯運(yùn)行,因?yàn)?nbsp;Java 程序的入口點(diǎn) main 方法必須是 static 的。當(dāng)你去掉所有 static 后,會(huì)遇到以下問題:
main方法必須是static
Java 虛擬機(jī)(JVM)啟動(dòng)時(shí),會(huì)直接調(diào)用 public static void main(String[] args) 方法,而不需要?jiǎng)?chuàng)建類的實(shí)例。如果去掉 static,JVM 無法直接調(diào)用 main 方法,會(huì)拋出錯(cuò)誤:

靜態(tài)方法中不能引用非靜態(tài)成員
如果 main 保持 static,但其他方法 / 類去掉 static,會(huì)導(dǎo)致:
- 靜態(tài)方法
main無法直接調(diào)用非靜態(tài)方法(如swap)或創(chuàng)建非靜態(tài)內(nèi)部類(如MyValue)的實(shí)例 例如:

必須先創(chuàng)建 Main 的實(shí)例,再通過實(shí)例調(diào)用:

解決方案:保留必要的static
如果你想去掉 static,需要重構(gòu)整個(gè)程序結(jié)構(gòu),例如:
- 將
main改為非靜態(tài)(但 JVM 無法直接啟動(dòng),需通過其他類調(diào)用)。 - 創(chuàng)建類的實(shí)例來調(diào)用方法(違背 Java 程序的常規(guī)寫法)。
這種重構(gòu)會(huì)讓代碼變得復(fù)雜,通常不推薦。更合理的做法是:
- 保留
main和工具方法(如swap)的static,確保程序可運(yùn)行。 - 僅在需要對(duì)象狀態(tài)時(shí)使用非靜態(tài)成員(如實(shí)例變量、方法)。
總結(jié)
不能去掉所有 static,因?yàn)?nbsp;main 必須是 static 的。但可以根據(jù)需求調(diào)整:
- 工具類方法(如
swap)通常設(shè)為static,方便直接調(diào)用。 - 內(nèi)部類若需在靜態(tài)環(huán)境使用,需聲明為
static。 - 對(duì)象相關(guān)的成員(如實(shí)例變量、方法)保持非靜態(tài)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring?Data?JPA?實(shí)體類中常用注解說明
這篇文章主要介紹了Spring?Data?JPA?實(shí)體類中常用注解說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
java使用BeanUtils.copyProperties踩坑經(jīng)歷
最近在做個(gè)項(xiàng)目,踩了個(gè)坑特此記錄一下,本文主要介紹了使用BeanUtils.copyProperties踩坑經(jīng)歷,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
Java并發(fā)volatile可見性的驗(yàn)證實(shí)現(xiàn)
這篇文章主要介紹了Java并發(fā)volatile可見性的驗(yàn)證實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
Spring注解@Qualifier的詳細(xì)用法你知道幾種
本文給大家分享Spring注解@Qualifier的詳細(xì)用法,包括@Autowired和@Resource區(qū)別介紹,本文通過示例代碼給大家詳細(xì)介紹,感興趣的朋友跟隨小編一起看看吧2021-07-07
Spring事務(wù)中@Transactional注解不生效的原因分析與解決
在Spring框架中,@Transactional注解是管理數(shù)據(jù)庫事務(wù)的核心方式,本文將深入分析事務(wù)自調(diào)用的底層原理,解釋為什么事務(wù)不生效,并提供多種解決方案,希望對(duì)大家有所幫助2025-03-03

