乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      淺析Java中的final關(guān)鍵字

       fengshenwonder 2015-10-10

      淺析Java中的final關(guān)鍵字

        談到final關(guān)鍵字,想必很多人都不陌生,在使用匿名內(nèi)部類的時候可能會經(jīng)常用到final關(guān)鍵字。另外,Java中的String類就是一個final類,那么今天我們就來了解final這個關(guān)鍵字的用法。下面是本文的目錄大綱:

        一.final關(guān)鍵字的基本用法

        二.深入理解final關(guān)鍵字

        若有不正之處,請多多諒解并歡迎指正。

        請尊重作者勞動成果,轉(zhuǎn)載請標(biāo)明原文鏈接:

        http://www.cnblogs.com/dolphin0520/p/3736238.html

      一.final關(guān)鍵字的基本用法

        在Java中,final關(guān)鍵字可以用來修飾類、方法和變量(包括成員變量和局部變量)。下面就從這三個方面來了解一下final關(guān)鍵字的基本用法。

        1.修飾類

        當(dāng)用final修飾一個類時,表明這個類不能被繼承。也就是說,如果一個類你永遠不會讓他被繼承,就可以用final進行修飾。final類中的成員變量可以根據(jù)需要設(shè)為final,但是要注意final類中的所有成員方法都會被隱式地指定為final方法。

        在使用final修飾類的時候,要注意謹(jǐn)慎選擇,除非這個類真的在以后不會用來繼承或者出于安全的考慮,盡量不要將類設(shè)計為final類。

        2.修飾方法

        下面這段話摘自《Java編程思想》第四版第143頁:

        “使用final方法的原因有兩個。第一個原因是把方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率。在早期的Java實現(xiàn)版本中,會將final方法轉(zhuǎn)為內(nèi)嵌調(diào)用。但是如果方法過于龐大,可能看不到內(nèi)嵌調(diào)用帶來的任何性能提升。在最近的Java版本中,不需要使用final方法進行這些優(yōu)化了?!?/p>

        因此,如果只有在想明確禁止 該方法在子類中被覆蓋的情況下才將方法設(shè)置為final的。

        注:類的private方法會隱式地被指定為final方法。

        3.修飾變量

        修飾變量是final用得最多的地方,也是本文接下來要重點闡述的內(nèi)容。首先了解一下final變量的基本語法:

        對于一個final變量,如果是基本數(shù)據(jù)類型的變量,則其數(shù)值一旦在初始化之后便不能更改;如果是引用類型的變量,則在對其初始化之后便不能再讓其指向另一個對象。

        舉個例子:

        

        上面的一段代碼中,對變量i和obj的重新賦值都報錯了。

      二.深入理解final關(guān)鍵字

        在了解了final關(guān)鍵字的基本用法之后,這一節(jié)我們來看一下final關(guān)鍵字容易混淆的地方。

      1.類的final變量和普通變量有什么區(qū)別?

        當(dāng)用final作用于類的成員變量時,成員變量(注意是類的成員變量,局部變量只需要保證在使用之前被初始化賦值即可)必須在定義時或者構(gòu)造器中進行初始化賦值,而且final變量一旦被初始化賦值之后,就不能再被賦值了。

        那么final變量和普通變量到底有何區(qū)別呢?下面請看一個例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      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));
          }
      }

        

      View Code

        大家可以先想一下這道題的輸出結(jié)果。為什么第一個比較結(jié)果為true,而第二個比較結(jié)果為fasle。這里面就是final變量和普通變量的區(qū)別了,當(dāng)final變量是基本數(shù)據(jù)類型以及String類型時,如果在編譯期間能知道它的確切值,則編譯器會把它當(dāng)做編譯期常量使用。也就是說在用到該final變量的地方,相當(dāng)于直接訪問的這個常量,不需要在運行時確定。這種和C語言中的宏替換有點像。因此在上面的一段代碼中,由于變量b被final修飾,因此會被當(dāng)做編譯器常量,所以在使用到b的地方會直接將變量b 替換為它的  值。而對于變量d的訪問卻需要在運行時通過鏈接來進行。想必其中的區(qū)別大家應(yīng)該明白了,不過要注意,只有在編譯期間能確切知道final變量值的情況下,編譯器才會進行這樣的優(yōu)化,比如下面的這段代碼就不會進行優(yōu)化:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      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";
          }
      }

        這段代碼的輸出結(jié)果為false。

      2.被final修飾的引用變量指向的對象內(nèi)容可變嗎?

        在上面提到被final修飾的引用變量一旦初始化賦值之后就不能再指向其他的對象,那么該引用變量指向的對象的內(nèi)容可變嗎?看下面這個例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public class Test {
          public static void main(String[] args)  {
              final MyClass myClass = new MyClass();
              System.out.println(++myClass.i);
          }
      }
      class MyClass {
          public int i = 0;
      }

        這段代碼可以順利編譯通過并且有輸出結(jié)果,輸出結(jié)果為1。這說明引用變量被final修飾之后,雖然不能再指向其他對象,但是它指向的對象的內(nèi)容是可變的。

      3.final和static

        很多時候會容易把static和final關(guān)鍵字混淆,static作用于成員變量用來表示只保存一份副本,而final的作用是用來保證變量不可變。看下面這個例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      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();
      }

        運行這段代碼就會發(fā)現(xiàn),每次打印的兩個j值都是一樣的,而i的值卻是不同的。從這里就可以知道final和static變量的區(qū)別了。

      4.匿名內(nèi)部類中使用的外部局部變量為什么只能是final變量?

        這個問題請參見上一篇博文中《Java內(nèi)部類詳解》中的解釋,在此處不再贅述。

      5.關(guān)于final參數(shù)的問題

        關(guān)于網(wǎng)上流傳的”當(dāng)你在方法中不需要改變作為參數(shù)的對象變量時,明確使用final進行聲明,會防止你無意的修改而影響到調(diào)用方法外的變量“這句話,我個人理解這樣說是不恰當(dāng)?shù)摹?/p>

        因為無論參數(shù)是基本數(shù)據(jù)類型的變量還是引用類型的變量,使用final聲明都不會達到上面所說的效果。

        看這個例子就清楚了:

        上面這段代碼好像讓人覺得用final修飾之后,就不能在方法中更改變量i的值了。殊不知,方法changeValue和main方法中的變量i根本就不是一個變量,因為java參數(shù)傳遞采用的是值傳遞,對于基本類型的變量,相當(dāng)于直接將變量進行了拷貝。所以即使沒有final修飾的情況下,在方法內(nèi)部改變了變量i的值也不會影響方法外的i。

        再看下面這段代碼:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      public class Test {
          public static void main(String[] args)  {
              MyClass myClass = new MyClass();
              StringBuffer buffer = new StringBuffer("hello");
              myClass.changeValue(buffer);
              System.out.println(buffer.toString());
          }
      }
      class MyClass {
           
          void changeValue(final StringBuffer buffer) {
              buffer.append("world");
          }
      }

        運行這段代碼就會發(fā)現(xiàn)輸出結(jié)果為 helloworld。很顯然,用final進行修飾并沒有阻止在changeValue中改變buffer指向的對象的內(nèi)容。有人說假如把final去掉了,萬一在changeValue中讓buffer指向了其他對象怎么辦。有這種想法的朋友可以自己動手寫代碼試一下這樣的結(jié)果是什么,如果把final去掉了,然后在changeValue中讓buffer指向了其他對象,也不會影響到main方法中的buffer,原因在于java采用的是值傳遞,對于引用變量,傳遞的是引用的值,也就是說讓實參和形參同時指向了同一個對象,因此讓形參重新指向另一個對象對實參并沒有任何影響。

        所以關(guān)于網(wǎng)上流傳的final參數(shù)的說法,我個人不是很贊同。

      參考資料:

        《Java編程思想》

       淺析Java中的final關(guān)鍵字

        談到final關(guān)鍵字,想必很多人都不陌生,在使用匿名內(nèi)部類的時候可能會經(jīng)常用到final關(guān)鍵字。另外,Java中的String類就是一個final類,那么今天我們就來了解final這個關(guān)鍵字的用法。下面是本文的目錄大綱:

        一.final關(guān)鍵字的基本用法

        二.深入理解final關(guān)鍵字

        若有不正之處,請多多諒解并歡迎指正。

        請尊重作者勞動成果,轉(zhuǎn)載請標(biāo)明原文鏈接:

        http://www.cnblogs.com/dolphin0520/p/3736238.html

      一.final關(guān)鍵字的基本用法

        在Java中,final關(guān)鍵字可以用來修飾類、方法和變量(包括成員變量和局部變量)。下面就從這三個方面來了解一下final關(guān)鍵字的基本用法。

        1.修飾類

        當(dāng)用final修飾一個類時,表明這個類不能被繼承。也就是說,如果一個類你永遠不會讓他被繼承,就可以用final進行修飾。final類中的成員變量可以根據(jù)需要設(shè)為final,但是要注意final類中的所有成員方法都會被隱式地指定為final方法。

        在使用final修飾類的時候,要注意謹(jǐn)慎選擇,除非這個類真的在以后不會用來繼承或者出于安全的考慮,盡量不要將類設(shè)計為final類。

        2.修飾方法

        下面這段話摘自《Java編程思想》第四版第143頁:

        “使用final方法的原因有兩個。第一個原因是把方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率。在早期的Java實現(xiàn)版本中,會將final方法轉(zhuǎn)為內(nèi)嵌調(diào)用。但是如果方法過于龐大,可能看不到內(nèi)嵌調(diào)用帶來的任何性能提升。在最近的Java版本中,不需要使用final方法進行這些優(yōu)化了。“

        因此,如果只有在想明確禁止 該方法在子類中被覆蓋的情況下才將方法設(shè)置為final的。

        注:類的private方法會隱式地被指定為final方法。

        3.修飾變量

        修飾變量是final用得最多的地方,也是本文接下來要重點闡述的內(nèi)容。首先了解一下final變量的基本語法:

        對于一個final變量,如果是基本數(shù)據(jù)類型的變量,則其數(shù)值一旦在初始化之后便不能更改;如果是引用類型的變量,則在對其初始化之后便不能再讓其指向另一個對象。

        舉個例子:

        

        上面的一段代碼中,對變量i和obj的重新賦值都報錯了。

      二.深入理解final關(guān)鍵字

        在了解了final關(guān)鍵字的基本用法之后,這一節(jié)我們來看一下final關(guān)鍵字容易混淆的地方。

      1.類的final變量和普通變量有什么區(qū)別?

        當(dāng)用final作用于類的成員變量時,成員變量(注意是類的成員變量,局部變量只需要保證在使用之前被初始化賦值即可)必須在定義時或者構(gòu)造器中進行初始化賦值,而且final變量一旦被初始化賦值之后,就不能再被賦值了。

        那么final變量和普通變量到底有何區(qū)別呢?下面請看一個例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      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));
          }
      }

        

      View Code

        大家可以先想一下這道題的輸出結(jié)果。為什么第一個比較結(jié)果為true,而第二個比較結(jié)果為fasle。這里面就是final變量和普通變量的區(qū)別了,當(dāng)final變量是基本數(shù)據(jù)類型以及String類型時,如果在編譯期間能知道它的確切值,則編譯器會把它當(dāng)做編譯期常量使用。也就是說在用到該final變量的地方,相當(dāng)于直接訪問的這個常量,不需要在運行時確定。這種和C語言中的宏替換有點像。因此在上面的一段代碼中,由于變量b被final修飾,因此會被當(dāng)做編譯器常量,所以在使用到b的地方會直接將變量b 替換為它的  值。而對于變量d的訪問卻需要在運行時通過鏈接來進行。想必其中的區(qū)別大家應(yīng)該明白了,不過要注意,只有在編譯期間能確切知道final變量值的情況下,編譯器才會進行這樣的優(yōu)化,比如下面的這段代碼就不會進行優(yōu)化:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      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";
          }
      }

        這段代碼的輸出結(jié)果為false。

      2.被final修飾的引用變量指向的對象內(nèi)容可變嗎?

        在上面提到被final修飾的引用變量一旦初始化賦值之后就不能再指向其他的對象,那么該引用變量指向的對象的內(nèi)容可變嗎?看下面這個例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public class Test {
          public static void main(String[] args)  {
              final MyClass myClass = new MyClass();
              System.out.println(++myClass.i);
          }
      }
      class MyClass {
          public int i = 0;
      }

        這段代碼可以順利編譯通過并且有輸出結(jié)果,輸出結(jié)果為1。這說明引用變量被final修飾之后,雖然不能再指向其他對象,但是它指向的對象的內(nèi)容是可變的。

      3.final和static

        很多時候會容易把static和final關(guān)鍵字混淆,static作用于成員變量用來表示只保存一份副本,而final的作用是用來保證變量不可變??聪旅孢@個例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      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();
      }

        運行這段代碼就會發(fā)現(xiàn),每次打印的兩個j值都是一樣的,而i的值卻是不同的。從這里就可以知道final和static變量的區(qū)別了。

      4.匿名內(nèi)部類中使用的外部局部變量為什么只能是final變量?

        這個問題請參見上一篇博文中《Java內(nèi)部類詳解》中的解釋,在此處不再贅述。

      5.關(guān)于final參數(shù)的問題

        關(guān)于網(wǎng)上流傳的”當(dāng)你在方法中不需要改變作為參數(shù)的對象變量時,明確使用final進行聲明,會防止你無意的修改而影響到調(diào)用方法外的變量“這句話,我個人理解這樣說是不恰當(dāng)?shù)摹?/p>

        因為無論參數(shù)是基本數(shù)據(jù)類型的變量還是引用類型的變量,使用final聲明都不會達到上面所說的效果。

        看這個例子就清楚了:

        上面這段代碼好像讓人覺得用final修飾之后,就不能在方法中更改變量i的值了。殊不知,方法changeValue和main方法中的變量i根本就不是一個變量,因為java參數(shù)傳遞采用的是值傳遞,對于基本類型的變量,相當(dāng)于直接將變量進行了拷貝。所以即使沒有final修飾的情況下,在方法內(nèi)部改變了變量i的值也不會影響方法外的i。

        再看下面這段代碼:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      public class Test {
          public static void main(String[] args)  {
              MyClass myClass = new MyClass();
              StringBuffer buffer = new StringBuffer("hello");
              myClass.changeValue(buffer);
              System.out.println(buffer.toString());
          }
      }
      class MyClass {
           
          void changeValue(final StringBuffer buffer) {
              buffer.append("world");
          }
      }

        運行這段代碼就會發(fā)現(xiàn)輸出結(jié)果為 helloworld。很顯然,用final進行修飾并沒有阻止在changeValue中改變buffer指向的對象的內(nèi)容。有人說假如把final去掉了,萬一在changeValue中讓buffer指向了其他對象怎么辦。有這種想法的朋友可以自己動手寫代碼試一下這樣的結(jié)果是什么,如果把final去掉了,然后在changeValue中讓buffer指向了其他對象,也不會影響到main方法中的buffer,原因在于java采用的是值傳遞,對于引用變量,傳遞的是引用的值,也就是說讓實參和形參同時指向了同一個對象,因此讓形參重新指向另一個對象對實參并沒有任何影響。

        所以關(guān)于網(wǎng)上流傳的final參數(shù)的說法,我個人不是很贊同。

      參考資料:

        《Java編程思想》

       

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多