<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                Java的關鍵字final通常是指被它修飾的數據是不能被改變的,不想改變可能出于兩種理由:設計或效率。主要特性: * final數據的使用 * final參數的使用 * final方法的使用 * final類不能被繼承 ### final數據 **1.1 final修飾變量** final 變量一經初始化,就不能改變其值 這里的值對于一個對象或者數組來說指的是這個對象或者數組的引用地址。因此,一個線程定義了一個final變量之后,其他任意線程都拿到這個變量。但有一點需要注意的是,當這個final變量為對象或者數組時,雖然我們不能講這個變量賦值為其他對象或者數組,但是我們可以改變對象的域或者數組中的元素; > final域能確保初始化過程的安全性,從而可以不受限制地訪問不可變對象,并在共享這些對象時無須同步; 線程對這個對象變量的域或者數據的元素的改變不具有線程可見性; 所以final修飾的變量必須被初始化 ``` public static final String LOAN = "loan"; LOAN = new String("loan") //invalid compilation error ``` final變量初始化時機: * 定義時初始化 * 初始化塊中,但不可在靜態初始化塊中,靜態的final實例變量才可以在靜態初始化塊中 * 構造方法中,但靜態final實例變量不可以在其中 特性 * 修飾的變量是基本數據類型:告知編譯器這一塊數據是不變的,這樣可以在執行計算時,減少一些運行時的負擔; * final變量必須在聲明時被初始化; * final實例變量必須在所有的構造函數末尾初始化; * 在JMM中要求final域的初始化動作必須在構造方法return之前完成; ``` package com.quancheng; import java.util.Random; public class FinalTest { private static Random random = new Random(20); private final int VALUE_A = 10; private static final int VALUE_B = 20; public static final int VALUE_C = random.nextInt(10); public final int VALUE_D = random.nextInt(10); public static void main(String[] args) { FinalTest test = new FinalTest(); //test.VALUE_A = 5;//Error:不可以這樣做 //test.VALUE_B =21;//Error:不可以這樣做 FinalTest finalT = new FinalTest(); FinalTest finalT1 = new FinalTest(); System.out.println("VALUE_C:"+VALUE_C); System.out.println("VALUE_C:"+finalT.VALUE_C); System.out.println("VALUE_C:"+finalT1.VALUE_C); System.out.println("---------"); System.out.println("VALUE_D:"+finalT.VALUE_D); System.out.println("VALUE_D:"+finalT1.VALUE_D); } } output==> VALUE_C:3 VALUE_C:3 VALUE_C:3 --------- VALUE_D:1 VALUE_D:1 ``` 以上結果得出一點我們不能因為某數據時final的就認為在編譯時可以知道它的值。在運行時使用隨機生成的VALUE\_C和VALUE\_D說明了這一點。示例代碼展示了final數值定義為static和非static的區別。此區別只有當數值在運行時內被初始化時才會顯現,這是因為編譯器對編譯時數值一視同仁(并且他們可能因為優化而消失)。使用static final 的數值是不可以通過一個新的對象而改變的。這是因為在裝載時已經被初始化,而不是每次創建新對象時初始化。 **1.2 final用于引用** 當使用final用于對對象的引用而不是基本類型時,對于基本類型final使數值恒定不變,而對于對象引用,final使引用恒定不變。一旦引用被初始化指向一個對象,就無法再把它改為指向另一個對象。然而,對象自身的數據是可以修改的 ``` package com.game.lll; public class FinalTest { private final int a = 10; private final Value v1 = new Value(10); public static void main(String[] args) { FinalTest test = new FinalTest(); //test.a = 5;//不可以這樣做 test.v1.value++; //test.v1 = new Value(12);//Error:不可以這樣做 System.out.println("對象內的數據:"+test.v1.value); } class Value{ int value; public Value(int value) { this.value = value; } } } ``` **1.3 final用于數組** final用于數組和引用時一樣的,數組只不過是另一種引用,對于這個變量的引用是不能被重新賦值,但是對象本身是可以修改的。代碼如下: ``` package com.game.lll; public class FinalTest { private final Value v1 = new Value(10); private final int[] values = { 1, 2, 3, 4, 5, 6 }; public static void main(String[] args) { FinalTest test = new FinalTest(); //test.a = 5;//不可以這樣做 test.v1.value++; //test.v1 = new Value(12);//Error:不可以這樣做 test.values[0] = 100;//對象本身是可以修改的 for(int i = 0; i < test.values.length;i++){ System.out.println(test.values[i]++);//對于這個變量的引用是不能被重新賦值 } } class Value{ int value; public Value(int value) { this.value = value; } } } ``` **1.4 空白final** Java允許生成“空白final”,空白final是指被聲明為final但又給未定初值的域。代碼如下: ``` package com.game.lll; public class BlankFinal { private final int a; public BlankFinal(int i) { this.a = i; } public static void main(String[] args) { BlankFinal blankFinal = new BlankFinal(5); System.out.println(blankFinal.a); } } ``` 雖然未對a直接賦值,但是在構造函數中對a進行了初始化。所以無論什么情況,都要確保final在使用前被初始化 > 在JMM中要求final域的初始化動作必須在構造方法return之前完成 ### final方法 使用final方法的原因是把方法鎖定,以防任何繼承類修改它的含義。final聲明的方法不能被重寫; * 當調用final方法時,直接將方法主體插入到調用處,而不是進行方法調用,這樣能提高程序效率\(內聯機制\) * 如果你認為一個方法的功能已經足夠完整了,子類中不需要改變的話,你可以聲明此方法為final * final方法比非final方法快,因為在編譯時候已靜態綁定了,不需要在運行時再動態綁定 ``` class PersonalLoan{ public final String getName(){ return "personal loan"; } } class CheapPersonalLoan extends PersonalLoan{ @Override public final String getName(){ return "cheap personal loan"; //compilation error: overridden method is final } } ``` ### final類 當你將某個類定義為final class時,那么子類就無法繼承該類 思考一個有趣的現象: ``` byte b1=1; byte b2=3; byte b3=b1+b2; //當程序執行到這一行的時候會出錯,因為b1、b2可以自動轉換成int類型的變量,運算時java虛擬機對它進行了轉換,結果導致把一個int賦值給byte final byte b1=1; final byte b2=3; byte b3=b1+b2; //不會出錯,相信你看了上面的解釋就知道原因了。 ``` ### 其它特性 * final變量一經初始化,就不能改變其值; * final變量應該全部應用大寫(編碼規則); * final類的所有方法為隱式的final方法; * 類不能同時被聲明為final和abstract; ### 知識點 * 為何System類中的out/err可以更改值 ``` public final static InputStream in = null; public final static PrintStream out = null; public final static PrintStream err = null; ``` setOut/setIn/setErr是native方法,可以繞過java語言的存取控制機制;這種罕見的情況來自早期JAVA,并且不會再其它地方遇到; ``` private static native void setIn0(InputStream in); private static native void setOut0(PrintStream out); private static native void setErr0(PrintStream err); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看