關於Final關鍵字和不變性的深入理解

2021-10-05 21:59:57 字數 2569 閱讀 1669

人已走

車未動心已動

身未起若有所思

茫然無措

不變性和final的關係?

面試題推薦閱讀:jvm類載入

如果物件在被建立後,狀態就不能被修改,那麼它就是不可變的。

具有不可變的物件一定是執行緒安全的,我們不需要對其採取任何額外的安全措施,也能保證執行緒安全。

類防止被繼承

方法防止被重寫

變數防止被修改

天生是執行緒安全的,而不需要額外的同步開銷

被final修飾的變數,意味著值不能被修改。如果變數是物件,那麼物件的引用不能變,但是物件自身的內容依然可以變化

屬性被宣告為final後,該變數則只能被賦值一次,且一旦被賦值,final的變數就不能再被修改,無論如何也不會變。

賦值時機

為什麼要規定賦值時機?

如果初始化不賦值,後續賦值,就是從null變成你的賦值,這就違反了final不變的原則了。

在宣告變數的等號右邊直接賦值

class

demo

在建構函式中賦值

class

demo

}

在類的初始**塊中賦值(不常用)

class

demo

}

如果不採用第一種賦值方法,那麼就必須在第2,3種挑乙個來賦值,而不能不賦值這是final語法所規定的。

等號右邊直接賦值

class

demo

static靜態**塊賦值

class

demo

}

和前面兩種不同,由於這裡的變數是在方法裡的,所以沒有建構函式,也不存在初始化**塊。

final local variable不規定賦值時機,只要求在使用前必須賦值,這和方法中的非final變數的要求也是一樣的。

而不用final修飾的方法變數在使用前也要初始化,又說明了方法變數預設使用final修飾,當多次賦值操作則變為非final變數。

引申:static修飾方法也不可被重寫,但可同名

例如典型的string類就是final的,我們從沒見過哪個類是繼承string類的。

不變性並不意味著簡單地用final修飾就是不可變。

對於基本型別,確實被final修飾後就具有不可變性。

但是對於物件型別,需要該物件保證自身被建立後,狀態永遠不會變才可以。

滿足下面條件時,物件才是不可變的。

物件建立後,其狀態就不能修改。

所有屬性都是final修飾的。

物件建立過程中沒有發生逸出。

在方法裡新建的區域性變數,實際上是儲存在每個執行緒私有的棧空間,而每個棧的棧空間是不能被其他執行緒所訪問到的,所以不會有執行緒安全問題。這就是著名的「棧封閉」技術,是「執行緒封閉」技術的一種情況。

public

class

main

}

結果

原因

//編譯期能確定的,發現和常量池a一樣,則直接指向a

string c=b+2;

//執行期確定的變數,分配在了堆上

string e=d+

2;

public

class

main

private

static string test()

}

結果

原因

//呼叫方法獲取值,編譯期也是確定不了

final string b=

test()

;

面試官問,你真的了解jvm類載入嗎?

final關鍵字與不變性

類中的static final屬性則有兩種賦值時機,除了在宣告變數的等號右邊直接賦值,還可以用static初始 塊賦值,而不能用普通的初始化 塊賦值 在方法中的final變數,由於方法中並沒有建構函式,也沒有初始化 塊,所以不規定賦值時機,只要求在變數使用前必須賦值 描述 演示棧封閉的兩種情況,基本...

併發安全 final關鍵字和不變性

例子 person物件,age和name都不能再變 不可變的物件,演示其他類無法修改這個物件,public也不行 public class person 具有不變性的物件一定是執行緒安全的,我們不需要對其採取任何額外的安全措施,也能保證執行緒安全 早期 現在final修飾變數 final修飾 3種變...

特徵提取之旋轉不變性和尺度不變性的通俗理解

特徵匹配 feature match 是計算機視覺中很多應用的基礎,比如說影象配準,攝像機跟蹤,三維重建,物體識別,人臉識別,所以花一些時間去深入理解這個概念是不為過的。本文希望通過一種通俗易懂的方式來闡述特徵匹配這個過程,以及在過程中遇到的一些問題。首先我通過幾張來指出什麼是特徵匹配,以及特徵匹配...