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

代碼輸出結果:

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

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

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

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

當然如果要賦值這樣還不夠,需要增加一個構造方法來初始化value的值



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

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

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

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

解決方案:保留必要的static
如果你想去掉 static,需要重構整個程序結構,例如:
- 將
main改為非靜態(tài)(但 JVM 無法直接啟動,需通過其他類調(diào)用)。 - 創(chuàng)建類的實例來調(diào)用方法(違背 Java 程序的常規(guī)寫法)。
這種重構會讓代碼變得復雜,通常不推薦。更合理的做法是:
- 保留
main和工具方法(如swap)的static,確保程序可運行。 - 僅在需要對象狀態(tài)時使用非靜態(tài)成員(如實例變量、方法)。
總結
不能去掉所有 static,因為 main 必須是 static 的。但可以根據(jù)需求調(diào)整:
- 工具類方法(如
swap)通常設為static,方便直接調(diào)用。 - 內(nèi)部類若需在靜態(tài)環(huán)境使用,需聲明為
static。 - 對象相關的成員(如實例變量、方法)保持非靜態(tài)。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
spring 整合 mybatis 中數(shù)據(jù)源的幾種配置方式(總結篇)
因為spring 整合mybatis的過程中, 有好幾種整合方式,尤其是數(shù)據(jù)源那塊,經(jīng)??吹讲灰粯拥呐渲梅绞?,總感覺有點亂,所以今天有空總結下,感興趣的朋友跟隨腳本之家小編一起學習吧2018-05-05
SpringBoot實現(xiàn)發(fā)送郵件功能過程圖解
這篇文章主要介紹了SpringBoot實現(xiàn)發(fā)送郵件功能過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03

