閱讀原文:小而有料的final(想聽文章核心內容語音對話版,請到微信公衆號——碼上實戰,閱讀原文)java
final這塊肉雖然小,但不可不知,由於不只面試可能會問,實際中也常使用。 就問你常量聲明時你爲何要加final?它有哪些做用?你思考過嗎?面試
final一般指被修飾的東西不能被改變的,不能被改變的緣由旺每每出於設計和效率的考慮。編程
先看final能修飾什麼?安全
不一樣的修飾有什麼不一樣的做用呢?下面慢慢道來:微信
final修飾的常量必須在被使用前進行初始化,初始化的方式無非兩種:定義時賦值或構造函數內賦值網絡
final修飾常量基本類型和引用類型有些不一樣,我分開講。dom
public class Test {
private final int A;
private final int B = 3;
private final int C = new Random().nextInt();
public Test() {
this.A = 5;
}
public Test(int a) {
this.A = a;
}
}
複製代碼
爲何常量B要用final修飾?函數
由於這種肯定值(定義便當即賦值)的final常量,編譯器會在編譯時將該常量值帶入到任何可能用到它的計算式中,這會減輕運行時的一些負擔。 好比 int d = 3 * B; 那麼編譯後至關於 int d = 9;this
final修飾的常量值是在編譯期間被肯定的嗎?spa
注意上面的變量C,咱們並不能覺得final修飾的就能在編譯時知道它的值,C的值只有在運行時被初始化時纔會顯現。
引用類型不能改變指的是引用被初始化指向一個對象後,就再也沒法改成指向其餘對象,但其指向的對象自己是能夠被修改的。
public class B {
//final常量d指向了對象D
private final D d =new D();
//這個方法改變了對象D的內容
public D change(){
this.d.setS("change");
return d;
}
//注意這個方法,將常量d的引用改變了
public D refnewD(){
this.d = new D();
return d;
}
class D {
private String s= "init";
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
}
}
複製代碼
上面代碼是沒法編譯的,由於this.d=new D()會提示Cannot assign a value to final variable 'd'
,可是你卻能夠調用change()方法來改變d對象的s變量值。
當一個方法被private修飾,這會隱式的指定爲final,這也會使得子類沒法覆蓋此方法,能夠對private方法增長final修飾,但對該方法並不能增長任何意義。
String類是final應用的典型例子,可去查看面試別再問我String了。
出於安全考慮或其餘緣由,你不但願該類有任何變更或被繼承。
一旦類被final修飾,即表明final類中的全部成員變量和方法都會隱式的final.
在方法的參數列表中將參數指定爲final,即表明該參數引用所指向的對象是沒法改變的; 若爲基本類型,則表示值能夠讀取,但沒法修改。修飾狀況和final常量相似。也可結合這題不會!別說你懂值傳遞與引用傳遞看。
public class C {
private final double A = 3.14D;
private static double b = 3.14D;
public static void main(String[] args) {
new C();
new C();
new C();
}
}
複製代碼
上面代碼運行後,A會存在3個,但b只有一個。
finally
是在異常處理時配合try-catch
執行清理操做,須要清理的資源包括:打開的文件或網絡鏈接等,它會把內存以外的資源恢復到他們的初始狀態。不管try中是否有異常出現,finally裏的操做都會被執行。
finalize
這是Object基類的一個方法,垃圾收集器在將對象清除出內存以前調用的清理資源方法,且此方法只會被系統調用一次,其實finalize能作的工做,try-finally能作的更好,《深刻理解Java虛擬機》中建議你們忘掉這個方法的存在。
更多精彩技術文章盡在微信公衆號:碼上實戰