Java面試題04-final關鍵字詳解
本篇博客將會討論java中final關鍵字的含義,以及final用在什么地方,感覺看書總會有一些模糊,而且解釋的不是很清楚,在此做個總結,以備准備面試的時候查看。針對每個解釋,會在需要的地方給出代碼說明,有興趣的讀者可自行實現。
轉載說明----------原文鏈接:隨風浪子90:http://www.cnblogs.com/liun1994/p/6691094.html
1. final關鍵字的含義
final表面意思就是不可更改的,恆量的意思;類似於C語言中的const關鍵字,指的是無法改變的量,這與靜態標量static是有區別的,靜態變量指的是只有一份存儲空間,值是可以改變的。使用final一定原因是出於軟件設計的角度,因為別人看到final這個關鍵字就知道是什么意思,達到心領神會的效果,但也正是由於這種"語義"的存在,在程序設計中要謹慎使用,以免誤用。
在Java中final修飾的就是常量,而且變量名要大寫;
Math類: public static final double E = 2.7182818284590452354; public static final double PI = 3.14159265358979323846; ......java源碼中好多變量都用final修飾
2. final的作用
final根據修飾位置的不同作用也不相同,針對三種情況:
1)修飾變量,被final修飾的變量必須要初始化,賦初值后不能再重新賦值。
注意:局部變量不在我們討論的范疇,因為局部變量本身就有作用范圍,不使用private、public等詞修飾。
2)修飾方法,被final修飾的方法代表不能重寫。
3)修飾類,被final修飾的類,不能夠被繼承。
注意:final修飾的類,類中的所有成員方法都被隱式地指定為final方法。
2.1 final修飾變量
被final修飾的變量必須顯示的初始化,初始化可以以三種方式:1)定義時初始化,2)在構造器中設置值,3)在非靜態塊中為final實例變量設置值。
final修飾變量指的是:這個變量被初始化后便不可改變,這里不可改變的意思對基本類型來說是其值不可變,而對於對象變量來說其引用不可變,即不能再指向其他的對象。
public class Test01{ final int x1= 10000; final int x2; final int x3; { x2 = 20000; } Public exe3(){ this.x3 = 3000; } }
如果final修飾的變量是對象類型,那么不可更改指的是該變量不可以再指向別的對象,但是對象的值時可以更改的,比如:
final Operate operate = new Operate() ;// operate有一個普通變量i初始化為10 operate.i = 11; operate.i = 12; System.out.println(operate.i); //輸出12 上述是自定義類,即便是數組,List等集合類型,所保存的值也是可以更改的。
3. final和static的區別
static作用於成員變量用來表示只保存一份副本,而final的作用是用來保證變量不可變,看一下網上的一個例子:
public class Test { 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); } } class MyClass { public final double i = Math.random(); public static double j = Math.random(); } //運行結果,兩次打印,j的值都是一樣的,j是static類型的屬於類,因此兩次值相同。i不是static的因此屬於對象,但是i的值是不可變的。
4. 其他final相關的知識
1)使用final關鍵字,如果編譯器能夠在編譯階段確定某變量的值,那么編譯器就會把該變量當做編譯期常量來使用。如果需要在運行時確定,那么編譯器就不會優化相關代碼。
public class Test { public static void main(String[] args) { String a = "hello2"; final String b = "hello"; String d = "hello"; String c = b + 2; String e = d + 2; System.out.println((a == c)); System.out.println((a == e)); } } //final類型,在編譯階段能夠確定值。 //非final類型在編譯階段確定不了 輸出: true false public class Test { public static void main(String[] args) { String a = "hello2"; final String b = getHello(); String c = b + 2; System.out.println((a == c)); } public static String getHello() { return "hello"; } } //即便是final類型,編譯階段也確定不了值。 輸出 false
2)注意不要將final與finally、finalize()等搞混。
3)將類、方法、變量聲明為final能夠提高性能,這樣JVM就有機會進行估計,然后優化。
4)接口中的變量都是public static final 的。
