值傳遞還是址傳遞昼窗,Java中使用final作為參數的修飾的感想

背景

最近在項目里經呈桥浚看到有的小伙伴喜歡在參數里面加上final關鍵字,平常也沒怎么注意澄惊,偶然幾天有空仔細看了一下唆途,覺得十分有意思。所以記錄下來掸驱,一方面是給自己多一些加深回憶的素材肛搬,另一方面也是希望能給與我有相同疑惑的同學有個參考。當然這個本身可能是比較基礎的問題毕贼,但是多換個角度看也蠻有意思的

final關鍵字在Java中的應用場景其實也還是蠻多的温赔,其中最出名的地方,應該就是繼承的時候不允許繼承吧鬼癣。然后還有很多的場景就是final static來定義一些常量吧陶贼。當然,還有一個比較有意思的場景待秃,就是今天我們的主角拜秧,在傳參時使用final關鍵字。

比如這樣:

public void doThings(final Object inputParam)

這里不由得聯想到了當年剛學C++中章郁,一個很有意思又很容易混淆的概念枉氮,參數時按址傳遞還是按值傳遞的呢?當然在Java中因為取消了 * 和 & 這些容易混淆的關鍵字暖庄,但是如果在傳遞參數時不注意的話聊替,還是很容易造成一些不容易發(fā)現的錯誤的。那么就想從使用final關鍵詞上來在看看Java有趣的傳參機制雄驹。


為什么在傳參中加上final

首先佃牛,我覺得還是給出一個大概的結論吧:

  1. int、char這些基礎類型來說医舆,可以認為就是按值傳遞的(在函數中對其的修改不會影響到參數本身來源的值得改變)俘侠。當然String這個類型會比較特殊,在于雖然本身是一個基礎類型蔬将,但是它同時又是一個對象爷速,有一些列Object中繼承的方法。(這里和String在內存中具體處理有關系霞怀,因為我們實際操作的是String其實是一個對象惫东,而真實的字串值是存在于靜態(tài)區(qū),并非是String本身毙石,這一點和裝箱類型的Integer之類的有點相似廉沮。具體有興趣的同學可以參考一下Java中內存結構,如內存模型的一個圖 謎之音:湊不要臉的徐矩! 我:是啊滞时,我就是,怎么了(捂臉)

  2. 對于對象來說滤灯,按照按值傳遞來處理坪稽,基本上也是沒有問題的,而且能夠簡化問題本身鳞骤。

  3. 但是(終于等到這個詞了窒百,據說是中國人最討厭的兩個字之一(捂臉)),在Java中其實也是可以直接改變參數對象的值的豫尽,只要你加上final關鍵字之后編譯器不報錯的話篙梢,而且這很好的彌補了有時我們返回值只有一個時的尷尬。

那么美旧,這是為啥呢庭猩,我們就來看看final關鍵字吧~其實就final本身來說,還是比較好理解的陈症,簡單的可以認為final就代表著不能改變的意思蔼水。可以發(fā)現录肯,不管是final在修飾變量趴腋,或者修飾方法,或者修飾類的時候论咏,其實都最最終意味著不可改變的意思优炬。
乍一聽,感覺有點玄乎厅贪,不可改變?yōu)樯缎揎椓藚抵蠓炊沟脜抵当旧砜梢愿淖兞四卮阑ぃ科鋵嵾@里和Java本身的機制有關,因為傳遞的是參數并非參數本身养涮,而是參數本身的一個引用的復制葵硕。這也就是很多文章將這里的傳遞和賦值號聯系起來的原因眉抬。具體可以參考這些文章,寫的挺好的:

所以參考下圖蜀变,我們可以發(fā)現,其實參數值的變化介评,是因為我們在內部可以通過引用來修改到參數值本身库北,但是其本質仍然是一個引用,而final定義的不可改變们陆,是引用的不可改變寒瓦,也就是引用本身是不能改變的(即不能指向其它對象!)

參數傳遞

所以引用的不可改變就表示了我們始終只能修改最初開始所指向的值本身坪仇,而不會因為修改成中間可能指向了其它值得引用本身杂腰。這里可能有點難以理解,我們可以通過以下代碼來加強理解一下:

public class AnPoJo {

    public int a = 1;
    
    @Override
    public String toString() {
        return String.valueOf(a);
    }
}


public class Application {

    public static void main(String[] args) {
        AnPoJo pojo = new AnPoJo();
        
        modify1(pojo);
        System.out.println("modify1: "+ pojo);
        modify2(pojo);
        System.out.println("modify2: " + pojo);     
    }
    
    private static AnPoJo modify1(AnPoJo pojo){
        pojo = new AnPoJo();
        pojo.a = 2;
        return pojo;
    } 
    
    private static AnPoJo modify2(AnPoJo pojo){
        pojo.a = 2;
        return pojo;
    }
}

打印結果如下:

modify1: 1
modify2: 2

由此可見烟很,其實只要引用本身不變化颈墅,是可以成功達到想要修改參數值的效果的。因此這里如果使用final關鍵字來標記想要直接改變參數值的方法是一個非常好的編程習慣雾袱,杜絕了疏忽可能導致的錯誤恤筛。例如可以這樣來修改方法modify1,通過編譯器就能很容易的檢測到錯誤點:

private static AnPoJo modify1(final AnPoJo pojo){
    pojo = new AnPoJo();    // compile error
    pojo.a = 2;
    return pojo;
} 

結語

其實有很多非常好的編程技巧芹橡,看似平淡無奇毒坛,但是仔細思考起來還是蠻有意思的一件事,能從中體會到優(yōu)秀代碼中對語言本身的理解和把握林说。除了本例之外煎殷,還有諸如其它一些例子,如: if(true==isValid())

當然由于知識結構所限腿箩,也有一個學習的過程豪直,如果有所錯誤或者遺漏,歡迎大家指正補充~
并在此給出一個簡單的結論:

  1. 如果不清楚到底是傳值還是傳址珠移,Java中就全部當做傳值處理就ok(除了部分特殊場景外弓乙,也不會有什么不足)
  2. 如果一定要改變參數值本身,一定要加final關鍵字钧惧!

enjoy~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末暇韧,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子浓瞪,更是在濱河造成了極大的恐慌懈玻,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乾颁,死亡現場離奇詭異涂乌,居然都是意外死亡艺栈,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門骂倘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眼滤,“玉大人巴席,你說我怎么就攤上這事历涝。” “怎么了漾唉?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵荧库,是天一觀的道長。 經常有香客問我赵刑,道長分衫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任般此,我火速辦了婚禮蚪战,結果婚禮上,老公的妹妹穿的比我還像新娘铐懊。我一直安慰自己邀桑,他們只是感情好,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布科乎。 她就那樣靜靜地躺著壁畸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茅茂。 梳的紋絲不亂的頭發(fā)上捏萍,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音空闲,去河邊找鬼令杈。 笑死,一個胖子當著我的面吹牛碴倾,可吹牛的內容都是我干的逗噩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼影斑,長吁一口氣:“原來是場噩夢啊……” “哼给赞!你這毒婦竟也來了?” 一聲冷哼從身側響起矫户,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤片迅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后皆辽,有當地人在樹林里發(fā)現了一具尸體柑蛇,經...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡芥挣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了耻台。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片空免。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盆耽,靈堂內的尸體忽然破棺而出蹋砚,到底是詐尸還是另有隱情,我是刑警寧澤摄杂,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布坝咐,位于F島的核電站,受9級特大地震影響析恢,放射性物質發(fā)生泄漏墨坚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一映挂、第九天 我趴在偏房一處隱蔽的房頂上張望泽篮。 院中可真熱鬧,春花似錦柑船、人聲如沸帽撑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽油狂。三九已至,卻和暖如春寸癌,著一層夾襖步出監(jiān)牢的瞬間专筷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工蒸苇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留磷蛹,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓溪烤,卻偏偏與公主長得像味咳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子檬嘀,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法槽驶,類相關的語法,內部類的語法鸳兽,繼承相關的語法掂铐,異常的語法,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現全陨,斷路器爆班,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 前言 人生苦多,快來 Kotlin 辱姨,快速學習Kotlin柿菩! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,209評論 9 118
  • 一:java概述:1雨涛,JDK:Java Development Kit枢舶,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,651評論 0 11
  • 當人生面臨重大困難或者磨難镜悉,最容易難住人的就是錢祟辟,錢支配著你的一切欲望医瘫,錢驅使著你的一切行為侣肄,雖然如此,錢也是最能...
    HJoanna閱讀 296評論 0 0