java中的 final 關鍵字 修飾引用時的問題

final使得被修飾的變量」不變」,可是因爲對象型變量的本質是「引用」,使得「不變」也有了兩種含義:引用自己的不變,和引用指向的對象不變。 
引用自己的不變:java

final StringBuffer a=new StringBuffer("immutable"); final StringBuffer b=new StringBuffer("not immutable"); a=b;//編譯期錯誤 
  • 1
  • 2
  • 3

引用指向的對象不變:多線程

final StringBuffer a=new StringBuffer("immutable"); final StringBuffer b=new StringBuffer("immutable"); a.append(b);//編譯經過
  • 1
  • 2
  • 3

可見,final只對引用的「值」(也即它所指向的那個對象的內存地址)有效,它迫使引用只能指向初始指向的那個對象,改變它的指向會致使編譯器錯誤。至於它所指向的對象的變化,final是不負責的。這很相似==操做符:==操做符只負責引用的「值」相等,至於這個地址所指向的對象內容是否相等,==操做符是無論的。app

理解final問題有很重要的含義。許多程序漏洞都基於此—-final只能保證引用永遠指向固定對象,不能保證那個對象的狀態不變。spa

在多線程的操做中,一個對象會被多個線程共享或修改,一個線程對對象無心識的修改可能會致使另外一個使用此對象的線程崩潰。一個錯誤的解決方法就是在此對象新建的時候把它聲明爲final,意圖使得它「永遠不變」。其實那是徒勞的。線程

相關文章
相關標籤/搜索