Java中的final
一 概念
在Java中, 可以使用final關鍵字修飾類、方法以及成員變量。
1 final標記的類不能被繼承
在設計類時候,如果這個類不需要有子類,類的實現細節不允許改變,並且確信這個類不會載被擴展,那麼就設計為final類。
2 final標記的方法不能被子類重寫
① 把方法鎖定,防止任何繼承類修改它的意義和實現
② 高效。編譯器在遇到調用final方法時候會轉入內嵌機製,大大提高執行效率
3 final標記的變量即成為常量,隻能被賦值一次
二 用法
1 對於引用類型和值類型來說
final的變量一旦被賦值,就不能再此改變。但對於引用類型,其“不可改變”的是指其地址不能改變而其屬性可以改變。
2 對於成員變量和局部變量來說
對於final的成員變量,對其賦值有兩種方式:① 聲明時即賦值;②構造方法中賦值。
對於final的局部變量,對其賦值有兩種方式:①聲明時即賦值;②使用的時候賦值。
例子一
public class Test
{
final int a;
final int b = 0;
public Test()
{
a = 0;
// b = 1;
}
public Test(int i)
{
a = 1;
}
public static void printFinal()
{
final int m = 100;
// m = 101;
final int n;
n = 102;
// n = 103;
System.out.println("m + n=" + m + n);
}
}
例子二
import cn.xy.model.Person;
public class Test2
{
final Person p = new Person("xy");
final Person p2;
public Test2()
{
p2 = new Person("xy");
p.setName("xyy");
// p = new Person("Jim");
// p = null;
}
public Test2(int i)
{
p2 = new Person("xy");
}
public static void printFinal()
{
final Person p = new Person("xy");
p.setName("xyy");
// p = new Person("Jim");
// p = null;
}
}
3 關於final修飾類和方法的例子這裏不舉例,讀者可以試一試。
三 final內存分配
調用一個函數除了函數本身的執行時間之外,還需要時間去尋找這個函數(類內部有一個函數簽名和函數地址的映射表)。故減少函數調用次數就等於降低了性能消耗。final修飾的函數會被編譯器優化,優化的結果是減少了函數調用的次數。
public class Test3
{
final void function()
{
System.out.println("xy");
}
public static void main(String[] args)
{
Test3 t = new Test3();
for(int i = 0;i<1000;i++)
{
t.function();
}
}
}
經過編譯器優化之後,這個類變成了相當於這樣寫:
public class Test3
{
final void function()
{
System.out.println("xy");
}
public static void main(String[] args)
{
Test3 t = new Test3();
for(int i = 0;i<1000;i++)
{
System.out.println("xy");
}
}
}
優點:
編譯器直接將function的函數體內嵌到了調用函數的地方,這樣的結果是節省了1000次函數調用,當然編譯器處理成字節碼,隻是我們可以想象成這樣,看個明白。
缺點:
當函數體若太長時用final會適得其反,因為經過編譯器內嵌之後代碼長度大大增加,於是就增加了jvm解釋字節碼的時間。而且如果final修飾的方法體過大的話,編譯器可能會放棄內聯。
原帖地址:https://blog.csdn.net/hupuxiang/article/details/7362267
最後更新:2017-04-03 05:40:33