final使得被修飾的變量"不變",但是由于對(duì)象型變量的本質(zhì)是“引用”,使得“不變”也有了兩種含義:引用本身的不變,和引用指向的對(duì)象不變。
引用本身的不變:
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
a=b;//編譯期錯(cuò)誤
引用指向的對(duì)象不變:
final StringBuffer a=new StringBuffer("immutable");
a.append(" broken!"); //編譯通過
可見,final只對(duì)引用的“值”(也即它所指向的那個(gè)對(duì)象的內(nèi)存地址)有效,它迫使引用只能指向初始指向的那個(gè)對(duì)象,改變它的指向會(huì)導(dǎo)致編譯期錯(cuò)誤。至于它所指向的對(duì)象的變化,final是不負(fù)責(zé)的。這很類似==操作符:==操作符只負(fù)責(zé)引用的“值”相等,至于這個(gè)地址所指向的對(duì)象內(nèi)容是否相等,==操作符是不管的。
理解final問題有很重要的含義。許多程序漏洞都基于此----final只能保證引用永遠(yuǎn)指向固定對(duì)象,不能保證那個(gè)對(duì)象的狀態(tài)不變。在多線程的操作中,一個(gè)對(duì)象會(huì)被多個(gè)線程共享或修改,一個(gè)線程對(duì)對(duì)象無意識(shí)的修改可能會(huì)導(dǎo)致另一個(gè)使用此對(duì)象的線程崩潰。一個(gè)錯(cuò)誤的解決方法就是在此對(duì)象新建的時(shí)候把它聲明為final,意圖使得它“永遠(yuǎn)不變”。其實(shí)那是徒勞的。
文章來源:http://www.cnblogs.com/rodney/archive/2005/08/18/217458.html