一、final修飾詞定義:
final關鍵字可用來修飾類別、變數與方法
final修飾變數時,表示該變數一旦獲得了初始值就不可被改變(嚴格來說:final修飾得變數不可被改變,一旦獲得初始值,該final變數就不能被重新賦值)
final既可以修飾成員變數(類別變數和實例變數),也可以修飾局部變數和形參
相關視訊學習教學:java線上學習
二、final成員變數語法規定:
final修飾的成員變數必須由程式設計師明確地指定初始值,系統不會對final成員進行隱式處初始化。
1、final修飾的類別變數、實例變數能製定初始值的地方如下:
類別變數:必須在靜態初始化區塊中指定初始值或宣告該類別變數時指定初始值,而且只能在兩個地方的其中之一指定
實例變數:必須在非靜態初始化區塊、宣告該實例變數或建構器中指定初始值,而且只能在三個地方的其中一個指定
注意:如果普通初始化區塊已經為某個實例變數指定了初始值,則不能再在建構器中為該實例變數制定初始值
下面程式示範了final修飾成員變數的效果:
package lextends; public class FinalVariableTest { //定义成员变量时指定默认值,合法 final int a = 6; //下面变量将在构造器或初始化块中分配初始值 final String str; final int c; final static double d; //既没有指定默认值,又没有在初始化块、构造器中指定初始值 //下面定义的ch实例是不合法的 //final char ch; //初始化块,可对没有指定默认值的实例变量指定初始值 { //在初始化块中为实例变量指定初始值,合法 str = "Hello"; //定义a实例变量时已经指定了默认值 //不能为a重新赋值,因此下面赋值语句非法 //a=9; } //静态初始化块,可对没有指定默认值的类变量指定初始值 static { //在静态初始化块中为类变量指定初始值,合法 d = 5.6; } //构造器,可以对既没有指定默认值,又没有在初始化块中,指定初始值的实例变量指定初始值 public FinalVariableTest() { //如果在初始化块中已经对str指定了初始值 //那么在构造器中不能对final变量重新赋值,下面赋值语句非法 //str="java" c = 5; } public void changeFinal() { //普通方法不能为final修饰的成员变量赋值 //d=1.2 //不能在普通方法中为final成员变量指定初始值 //ch = 'a'; } public static void mian(String[] args){ FinalVariableTest ft= new FinalVariableTest(); System.out.println(ft.a); System.out.println(ft.c); System.out.println(ft.d);} }
2、如果打算在建構器、初始化區塊對final成員變數進行初始化,則不要在初始化之前就存取成員變數的值。
package lextends; public class FinalErrorTest { //定义一个final修饰的实例变量 //系统不会对final成员变量进行默认初始化 final int age; { //age没有初始化,所以此处代码将引起错误,因为它试图访问一个未初始化的变量 //只要把定义age时的final修饰符去掉,程序就正确了 System.out.println(age); age=6; System.out.println(age); } public static void main(String[] args){ new FinalErrorTest(); } }
三、final局部變數
1、定義:系統不會對局部變數進行初始化,局部變數必須由程式設計師顯示初始化。因此使用final修飾局部變數時,既可以在定義時指定預設值,也可以不指定預設值。
下面程式示範了final修飾局部變數、形參:
(final修飾形參的情形,因為在呼叫此方法時,由系統根據傳入的參數來完成初始化,因此使用final修飾符不能被賦值。)
package lextends; public class FinalLocalVariable { public void test(final int a){ //不能对final修饰的形参赋值,下面语句非法 //a=5; } public static void mian(String[] args){ //定义final局部变量时指定默认值,则str变量无法重新赋值 final String str="hello"; //下面赋值语句非法 //str="Java"; //定义final局部变量时没有指定默认值,则d变量可被赋值一次 final double d; d=5.6; //对final变量重新赋值,下面语句非法 //d=6.4; } }
#四、final修飾基本型別變數和引用型別變數的差異
##使用final修飾的參考型別變數不能被重新賦值,但可以改變引用類型變數所引用對象的內容例如下面的iArr變數所引用的陣列對象,final修飾後的iArr變數不能被重新賦值,但iArr所引用數組的數組元素可以被改變eg. //final修饰数组元素,iArr是一个引用变量 final int[] iArr={5,6,12,9}; System.out.println(Arrays.toString(iArr)); //对数组元素进行排序,合法 Arrays.sort(iArr); System.out.println(Arrays.toString(iArr)); //对数组进行元素赋值,合法 iArr[2]=-8; System.out.println(Arrays.toString(iArr)); //下面语句对iArr重新赋值,非法 //iArr=null;
五、可執行」巨集取代「的final變數
1、對於一個final變數來說,不管它是類別變數、實例變量,還是局部變量,只要該變量滿足三個條件,這個final變量就不再是一個變量,而是相當於一個直接量。 (1)使用final修飾符修飾(2)在定義該final變數時指定了初始值(3)該初始值可以在編譯時就被確定下來2、final修飾符有一個重要用途就是定義」巨集變數「。當定義final變數時就為該變數指定了初始值,而且該變數可以在變數時就確定下來,那麼這個final變數本質上就是一個”宏變數“,編譯器會把程式中所有用到該變數的地方直接替換成該變數的值。 3、eg. String s1="疯狂Java"; //s2变量引用的字符串可以在编译时就确定下来 //因此s2直接引用变量池中已有的"疯狂Java"字符串 String s2="疯狂"+"Java"; System.out.println(s1==s2);//true //定义两个字符串直接量 String str1="疯狂"; String str2="Java"; String s3=str1+str2; System.out.println(s1==s3);//false對於s3而言,它的值由str1和str2進行連接運算得到的,由於str1、str2只是兩個普通變量,編譯器不會執行」宏替換“,因此編譯器無法確定s3的值,也就無法讓s3指向字串池中快取的"瘋狂Java"。 更多java相關文章教學可以存取:
以上是java物件導向之final修飾符的詳細內容。更多資訊請關注PHP中文網其他相關文章!