資料內(nèi)容:
final和static
很多時(shí)候會(huì)容易把static和final關(guān)鍵字混淆,static作用于成員變量用來(lái)表示只保存一份副本,而final的作用是用
來(lái)保證變量不可變??聪旅孢@個(gè)例子:
class MyClass {
public final double i = Math.random();
public static double j = Math.random();
}
public class Test2 {
public static void main(String[] args)
{ MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();
System.out.println(myClass1.i);
System.out.println(myClass1.j);
System.out.println(myClass2.i);
System.out.println(myClass2.j);
}
}
// 輸出:
// 0.6885279073145978
// 0.7678464493258529
// 0.5645174724833194
// 0.7678464493258529
運(yùn)行這段代碼就會(huì)發(fā)現(xiàn),每次打印的兩個(gè)j值都是一樣的,而i的值卻是不同的。從這里就可以知道final和static變
量的區(qū)別了。
final和volatitle
這兩個(gè)變量看起來(lái)沒(méi)有什么關(guān)系,但是我學(xué)習(xí)JAVA內(nèi)存模型時(shí),感覺(jué)兩者還是有很多異同,下面我簡(jiǎn)單總結(jié)一下。
禁止重排序規(guī)則:
對(duì)于volatitle,volatitle變量前面的賦值和取值,只能排在volatitle變量的前面,volatitle變量后面
賦值和取值,只能排在volatitle變量的后面,這個(gè)雷打不動(dòng)!至于volatitle變量前面的賦值和取值,
比如 a=1,b=2,他們的排序就不能保證了,可能是b=2,a=1,所以只能保證a和b是排在volatitle變
量前 面,volatitle變量后面的排序規(guī)則同上。(volatitle的排序規(guī)則,是針對(duì)volatitle的前后變量而言
的)
對(duì)于final,它的禁止重排序規(guī)則和它前后的變量沒(méi)有任何關(guān)系,可以排在final前,也可以排在final后。
final的禁止重排序規(guī)則是針對(duì)構(gòu)造函數(shù)而言的,也就是只有先給final賦值或者取值后,才能完成構(gòu)造
函數(shù)的初始化,但是普通變量,可能是先初始化構(gòu)造函數(shù),然后在給變量賦值。同理,當(dāng)獲取某個(gè)對(duì)象
時(shí),也是只能先成功獲取該對(duì)象的引用,再去獲取final成員變量的值,但是普通變量不能保證,可能會(huì)
導(dǎo)致普通變量的讀取,排在了獲取對(duì)象引用的前面。(final的排序規(guī)則,是針對(duì)final的成員變量和對(duì)
象的構(gòu)造函數(shù)而言)
內(nèi)存可見(jiàn)性:
兩者都有相同的內(nèi)存可見(jiàn)性,對(duì)于final,這個(gè)值都不變,所有的線程看到的值都是一樣的,當(dāng)然所有線
程可見(jiàn)。對(duì)于volatitle,它的值的改變,是強(qiáng)刷內(nèi)存的,同時(shí)也會(huì)讓其它線程的本地緩存的值也相應(yīng)改
變。
使用場(chǎng)景:
final主要是保證某個(gè)值不變,或者不類(lèi)不被繼承。volatitle主要是保證多個(gè)線程對(duì)該變量的內(nèi)存可
見(jiàn)性,常用于多個(gè)線程開(kāi)始、結(jié)束的標(biāo)記符等。所以說(shuō),兩者的使用場(chǎng)景,簡(jiǎn)直是風(fēng)馬牛不相及。