当前位置: 首页>JAVA>正文

java中的final關鍵字有哪些用法,Java: static,final,代碼塊 的詳解

java中的final關鍵字有哪些用法,Java: static,final,代碼塊 的詳解

Java: static,final,代碼塊 的詳解

在這里插入圖片描述


每博一文案

山本文緒說過這樣一句話:哪些決定放棄了的事,就請放棄得干干凈凈。哪些決定再也不見面的人,就真
的不要再見面了,不要再做背叛自己的事,如果想要愛別人,就先好好愛自己。	
人生是一場有去無回的旅行,舊日種種,結成過往,我們只能回過頭看,卻不能從頭走,好的也罷,壞的也罷,
過去的都已成定局了。不管是遺憾還是慶幸,都要帶著這份烙印,繼續走向漫漫人生。
正如那句極有名的禪語:無論你遇見誰,他都是對的人,無論發生什么事,那都是唯一會發生的事。
不管事情開始于那個時刻都是對的,時刻已經結束的,就是結束了。如果沒有失去,就不會懂得珍惜。
但是你知道嗎?如果已經失去了,就該學會放棄,沒有什么是注定會屬于我們的,得到或者失去,都是自有它的安排。
面對哪些注定要說再見到人或物,與其拼命拉扯,淚影婆娑,倒不如落落大方道一句“珍重”。
從從容容德告個別,然后留下一個瀟灑離開的背影,從今以后更加堅定自己的路,將自己的人生過得有聲有色。
愿你可飲最烈的酒,也能放開該放的手,從前不回頭,往后強求。——————   一禪心靈廟語

文章目錄

  • Java: static,final,代碼塊 的詳解
    • 每博一文案
    • 1. static 關鍵字
      • 1.1 static 修飾屬性
      • 1.2 static 修飾方法
      • 1.3 static 修飾代碼塊
      • 1.4 static 修飾內部類
      • 1.5 開發中如何合理的使用 staitc 關鍵字
    • 2. main 方法的探究
    • 3. 代碼塊
      • 3.1 程序中成員變量賦值的執行順序
    • 4. final 關鍵字
    • 5. 總結:
    • 6. 最后:


1. static 關鍵字

java中的final關鍵字有哪些用法?當我們編寫一個類時,其實就是在描述其對象的屬性和行為,而并沒有產生實質上 的對象,只有通過new關鍵字才會產生出對象,這時系統才會分配內存空間給對象, 其方法才可以供外部調用。我們有時候希望無論是否產生了對象或無論產生了多少 對象的情況下,某些特定的數據在內存空間里只有一份,例如所有的中國人都有個國家名稱,每一個中國人都共享這個國家名稱,不必在每一個中國人的實例對象中都單獨分配一個用于代表國家名稱的變量。這里我們就可以用到 static 關鍵字的使用了。

static : 表示的含義是 :靜態的

在Java類當中, static 可以修飾屬性,方法,代碼塊,內部類

1.1 static 修飾屬性

static 修飾屬性(變量): 按是否使用 static 修飾,可以分為為 靜態屬性(類屬性) VS 非靜態屬性(實例屬性)

類中static代碼段,非靜態屬性(實例屬性): 我們創建了類的多個對象,每個對象都獨立的擁有一套 類中的 非靜態屬性,非靜態變量對應不同的實例對象(new) 自身的修改,不會影響到其他的 對象當中的一套非靜態屬性。

靜態屬性(類屬性): 我們創建了類的多個對象,但是多個對象共享同一個靜態屬性,當通過某一個對象修改靜態屬性時,會導致其他對象調用此靜態變量時,是最后一次修改過的結果。

被 static 修飾的屬性的特點:

  • 靜態屬性隨著類的加載而加載,早于 new 對象的加載創建,因為 new 對象,要先加載類,再調用類中的構造方法創建對應的對象。
  • 在訪問權限允許的情況下,靜態屬性可以通過**“類名.靜態屬性名”** 的方式進行調用。
  • 由于類只會加載一次,則靜態屬性(靜態變量) 在內存(方法區)當中也只會存在一份,存在方法區的靜態域當中。
  • 靜態屬性有:System.out; Math.PI;
package blogs.blog2;public class StaticTest {public static void main(String[] args) {Chinese c1 = new Chinese();c1.nation = "CHN";Chinese c2 = new Chinese();c2.nation = "CHINA";System.out.println("c2.nation: "+c1.nation);System.out.println("c2.nation: "+c2.nation);// 可以通過 類名.靜態屬性 ()Chinese.nation = "中國";System.out.println("Chinese.nation: "+Chinese.nation);}
}class Chinese{String name;int age;static String nation;     // 被 static 修飾的靜態屬性}

在這里插入圖片描述

java 靜態塊和構造的執行順序,在這里插入圖片描述


1.2 static 修飾方法

被 staitc 修飾的方法,被稱為是 ”靜態方法“ 或者是 類方法。

靜態方法的特點:

  • 同樣靜態方法也是和隨著類的加載而加載到內存(方法區)當中的。
  • 在訪問權限允許的情況下,靜態屬性可以通過**“類名.靜態方法名”** 的方式進行調用。
  • 靜態方法只能調用 靜態的方法/屬性 ,無法調用非靜態的方法/屬性,除非 實例化對象(new)。因為一個(靜態方法)是已經在內存當中存在了的,調用一個(非靜態的)還沒有加載到內存當中的,JVM 是不允許的。
  • 在靜態的方法內:不能使用 'this’關鍵字 以及 super 關鍵字,他倆都是表示對象的引用.
  • 非靜態方法可以調用非靜態方法或屬性,也可以調用靜態方法或屬性。
  • 被 static 修飾的方法無法重寫

在這里插入圖片描述


靜態變量static。在這里插入圖片描述


在這里插入圖片描述

在這里插入圖片描述


package blogs.blog2;public class StaticTest {public static void main(String[] args) {// 靜態方法可以直接使用  “類名.靜態方法”調用Chinese.show();}
}class Chinese{String name;int age;static String nation;     // 被 static 修飾的靜態屬性public static void show(){System.out.println("我是靜態方法");// name = "TOM";  // 靜態方法無法直接調用非靜態的屬性// eat();   // 靜態方法無法直接調用非靜態的方法,可以通過 new 實例對象,調用/*this.name = "Tom";super.clone();*/  // 靜態方法中無法使用 this./super.// 靜態方法可以直接調用靜態屬性,靜態方法nation = "Hello";   // 靜態屬性sleep();            // 靜態方法}public void eat(){System.out.println("吃飯");System.out.println("***************************");// 非靜態方法可以直接調用 靜態方法/屬性,因為加載內存的先后原因nation = "World";     // 靜態屬性sleep();              // 靜態方法}public static void sleep() {System.out.println("睡覺");}
}

在這里插入圖片描述


static int?被 stiatic 修飾的方法,繼承時,無法被重寫,就算你按照重寫的要求,編寫好了沒有報錯,但是運行的時候,調用的是父類中沒有被重寫的方法 因為 stiatic 是類方法,和類一起加載到內存當中的,而多態中的重寫是,運行時類型,只有運行了。才

package blogs.blog2;public class StaticTest {public static void main(String[] args) {Earth earth = new Chinese();  // 多態earth.human();}}class Chinese extends Earth{public static void human() {System.out.println("中國人");}
}class Earth{public static void human(){System.out.println("人類");}}

在這里插入圖片描述


1.3 static 修飾代碼塊

被 static 修飾的代碼塊,被稱為 “靜態代碼塊”

具體詳細,繼續往下看,在 3.代碼塊 這一段有詳細說明

1.4 static 修飾內部類

關于這一部分內容,大家可以移步至:🔜🔜🔜

1.5 開發中如何合理的使用 staitc 關鍵字

開發中:如何確定一個屬性是否聲明未 static ???

如果一個屬性可以被多個對象共享的,不會隨著對象不同而不同的,就可以聲明為 staitc

一般 static 是和 final 一起修飾 變量的。

開發中:如何確定一個方法是否要聲明為 static 的 ???

一般是 stiatic 的屬性,通常對應的 set/get 方法也是 stiatic 的

工具類中的方法,習慣上聲明為 static 的,比如:Math,Arras,Collections


2. main 方法的探究

在這里插入圖片描述

  • public 權限修飾符為什么是 public ???

由于Java虛擬機需要調用類的 main() 方法,所以該方法的訪問權限 必須public 才行。

  • 為什么 main 方法的修飾符要是 static 靜態的 ???

因為Java虛擬機在執行 main() 方法時,不必創建對象,所以該方法必須是 static ,可以直接調用。

又因為 main 方法是 static 靜態的,靜態方法無法直接調用非靜態的方法/屬性,

必須創建對應類的實例對象(new)后,才能通過這個對象去訪問該對應類中的非靜態方法/屬性。

  • main 方法中的形參列表是 string[] args 字符串數組

該形參接收一個 String 類型的數組參數,該字符串數組中保存執行 java 命令時,所傳遞給所運行類的參數。

在這里插入圖片描述


main 也是一個方法,特殊之處就是,它是一個程序入口的方法。不同的類中的是可以相互調用 main 的方法的,如下

因為有兩個類,每個類中都有一個 main() 方法,所以執行的時候,你需要選擇,想要運行的是哪一個告知編譯器。

package blogs.blog2;public class MainTest {public static void main(String[] args) {System.out.println("我是 MainTest 中的 main()方法");}
}class Main2{public static void main(String[] args) {System.out.println("我要調用 MainTest中的main()方法");// 調用 MainTest 中的main()方法MainTest.main(args);}
}

在這里插入圖片描述


3. 代碼塊

在這里插入圖片描述

代碼塊(或初始化塊)的作用: 對Java類或者對象進行初始化

代碼塊的分類:

  • 一個類中代碼塊中若有修飾符,則只能被 static 修飾,被 static 修飾的代碼塊被稱為 靜態代碼塊
  • 沒有任何修飾符,修飾的代碼塊,被稱為非靜態代碼塊

靜態代碼塊的特點:

  • 可以有輸出語句
  • 可以對類的屬性,類的聲明進行初始化操作
  • 不可以對非靜態的屬性初始化,無法直接調用非靜態的的方法/屬性,想要 實例化對象 new
  • 靜態代碼塊隨著類的加載而加載,并執行,且執行一次。所以靜態代碼塊的執行要先于非靜態代碼塊
  • 一個類中可以有多個靜態代碼塊,若有多個靜態的代碼塊,那么按照從上到下的順序依次執行。
  • 靜態的代碼塊的諸多限制和 “staitc" 是一樣的。

非靜態代碼塊的特點:

  • 和靜態代碼塊一樣可以有輸出語句
  • 可以對類的數,類的聲明進行初始化操作。
  • 不僅可以調用靜態的方法/屬性,也可以調用非靜態的方法 / 屬性
  • 一個類中可以有多個非靜態代碼塊,若有多個非靜態的代碼塊,那么按照從上到下的順序依次執行。
  • 注意的是非靜態代碼塊是,創建對象 (new) 的時候,才會執行,而且每創建一次對象都會執行一次,并且先于構造器執行。

無論是靜態代碼塊/還是非靜態代碼塊,都是加載后并執行的,并不是加載到內存當中不執行的。

在這里插入圖片描述


注意: 非靜態代碼塊,不是創建對象 (new) 是不會加載調用執行非靜態代碼塊的

package blogs.blog2;public class BlockTest {public static void main(String[] args) {Person.show();}
}class Person{String name;static String desc;public void eat() {System.out.println("非靜態方法");}public static void show(){System.out.println("靜態方法");}{System.out.println("非靜態代碼塊");}static{System.out.println("靜態代碼塊");// name = "Tom";  // 靜態代碼塊無法直接調用非靜態的// eat();}
}

在這里插入圖片描述


靜態代碼塊優先比非靜態代碼塊優先被執行,并且靜態代碼塊僅僅只是執行一次(加載類的那一次)

package blogs.blog2;public class BlockTest {public static void main(String[] args) {Person person = new Person();Person person2 = new Person();}
}class Person{String name;static String desc;public void eat() {System.out.println("非靜態方法");}public static void show(){System.out.println("靜態方法");}{System.out.println("非靜態代碼塊");}static{System.out.println("靜態代碼塊");// name = "Tom";  // 靜態代碼塊無法直接調用非靜態的// eat();}
}

在這里插入圖片描述


練習: 觀察如下代碼的運行結果:

先執行父類,再執行靜態代碼塊

package day15;public class LeafTest {public static void main(String[] args) {new Leaf();System.out.println("*************************");new Leaf();}
}class Root{static {System.out.println("Root的靜態初始化塊");}{System.out.println("Root的普通初始化塊");}public Root(){super();System.out.println("Root的無參數的構造器");}}class Mid extends Root{static{System.out.println("Mid的靜態初始化塊");}{System.out.println("Mid的普通初始化塊");}public Mid() {super();System.out.println("Mid的無參數的構造器");}public Mid(String msg) {// 通過this調用一類中的重載的構造器this();System.out.println("Mid的帶參數構造器,其參數數值: "+msg);}
}class Leaf extends Mid{static{System.out.println("Leaf的靜態初始化塊");}{System.out.println("Leaf的普通初始化塊");}public Leaf() {// 通過super調用父類中有一個字符串參數的構造器super("尚硅谷");System.out.println("Leaf的構造器");}
}

在這里插入圖片描述


package day15;public class Son extends Father {static {System.out.println("44444444444444444");}{System.out.println("55555555555555");}public Son() {System.out.println("66666666666666");}public static void main(String[] args) {System.out.println("77777777777");System.out.println("**********************************");new Son();System.out.println("*********************************");/*new Son();System.out.println("*************************************");new Father();*/}
}class Father{static{System.out.println("11111111111");}{System.out.println("222222222222");}public Father() {System.out.println("33333333333333");}
}

在這里插入圖片描述


3.1 程序中成員變量賦值的執行順序

如下是對屬性賦值的先后所執行的順序

  1. 默認初始化
  2. 顯式初始化
  3. 在代碼塊中賦值
  4. 構造器中初始化
  5. 有了對象以后,可以通過 ”對象.屬性,或對象.方法“ 的方式,進行賦值。
    在這里插入圖片描述
public class OrderTest {public static void main(String[] args) {Order order = new Order();System.out.println(order.orderId);}
}class Order{{orderId = 4;}int orderId = 3;public Order() {this.orderId = 5;}}

在這里插入圖片描述


把構造器初始化注釋掉,結果是

在這里插入圖片描述


4. final 關鍵字

final : 最終的含義。

final 可以用來修飾:類,方法,變量,局部變量(形參)

final 修飾一個,此類就不能被其他類所繼承了

比如:System 類,String 類,StringBuffer類:因為里面的方法基本都實現了,沒有必要再通過繼承擴展了。

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述


final 修飾方法:表明此方法不可以被重寫,比如:Object 類中的 getClass()

在這里插入圖片描述


在這里插入圖片描述


final 修飾屬性:可以考慮賦值的位置有:顯示初始化,代碼塊初始化,構造器,注意是:賦值不是修改,被 final 修飾的變量無法被修改了。

顯示初始化

package blogs.blog2;public class FinalTest {final int num = 10;public static void main(String[] args) {FinalTest f = new FinalTest();System.out.println(f.num);}
}

在這里插入圖片描述


代碼塊初始化:

package blogs.blog2;public class FinalTest {final int LEFT;{LEFT = 100;}public static void main(String[] args) {FinalTest f = new FinalTest();System.out.println(f.LEFT);}
}

在這里插入圖片描述


構造器初始化:

package blogs.blog2;public class FinalTest {final int num;public FinalTest(int n) {num = n;}public static void main(String[] args) {FinalTest f = new FinalTest(1000);System.out.println(f.num);}
}

在這里插入圖片描述


final 修飾局部變量(形參) 表明此形參時一個常量,當我們調用此方法時,給常量形參賦值一實參,一旦賦值以后,就只能在方法體中使用此形參,并且不能再進行重新的賦值操作了。

在這里插入圖片描述


package blogs.blog2;public class FinalTest {final int num;public FinalTest(final int n) {num = n;}public static void main(String[] args) {FinalTest f = new FinalTest(1000);System.out.println(f.num);}
}

一般是 static, final 用來修飾屬性,全局常量,需要注意的是一般 static 的成員屬性,方法也是 static 的

練習:

觀察如下代碼是否會出現報錯,如果不會報錯,運行的結果又是什么???

package blogs.blog2;public class FinalTest {public static void main(String[] args) {AA aa = new AA();aa.test(aa);}}class AA {String name;int age ;public void test(final AA aa) {aa.age = 10;   // 這里是否或報錯,能否編譯成功System.out.println(aa.age);}
}

在這里插入圖片描述


解析:

答:不會報錯,結果是 10 。

因為 final 修飾的是 AA 這個引用類型的形參,并不會作用于 AA 類中的屬性。

如果我修改 AA 這個引用類型的地址,可能就會報錯了。


5. 總結:

  1. static 修飾屬性,方法,代碼塊,內部類的不同的作用,
  2. static 靜態的隨著類一起加載到內存(方法區)當中(僅僅加載一次,所有對象共有),早于 new 對象的加載創建,因為 new 對象,要先加載類,再調用類中的構造方法創建對應的對象。
  3. static 靜態的屬性,方法,代碼塊 都無法直接的訪問非靜態的方法/屬性,需要通過 創建實例對象(new)的方式訪問
  4. 被 static 修飾的方法,無法被重寫,就算編寫成了重寫的方式了,但是調用的時候,執行的不是子類重寫的方法,而是父類中沒有被重寫的方法。
  5. main 方法的 public , static ,String[] args 的作用。
  6. 代碼塊:靜態代碼塊,非靜態代碼塊。
  7. 靜態代碼塊:隨著類一起加載到內存(方法區)當中,加載的同時,并執行代碼塊,并且(無論加載多少次類)只執行一次(加載類的那一次)。優先于非靜態代碼塊,優先于構造器。
  8. 非靜態代碼塊:只有當創建實例對象(new)的時候才會被加載并執行,創建多少次對象就會執行多少次非靜態代碼塊。
  9. final 最終的,可以修飾:屬性(不可修改),形參(不可修改),方法(無法重寫),類(無法繼承)。

6. 最后:

限于自身水平,其中存在的錯誤,希望大家給予指教,韓信點兵——多多益善,謝謝大家,后會有期,江湖再見!!!


在這里插入圖片描述

https://www.nshth.com/java/338462.html
>

相关文章:

  • java中的final關鍵字有哪些用法
  • 類中static代碼段
  • java 靜態塊和構造的執行順序
  • 靜態變量static
  • static int
  • final int
  • 代碼調用
  • cstatic
  • 有一個解謎的有外星人的游戲,【Pygame小游戲】 史上最經典的外星人游戲 ,全面保障 勇敢去闖 (未解之謎)
  • 2020年2月編程語言排行榜:Java第一,Python出現下滑!
  • 開一家手機配件店怎么樣,手機配件實體店好做不_震驚!手機實體店,你不得不防的套路!
  • bld設計公司,BLE外設設計
  • 手機如何連接外設,iOS 連接外設的幾種方式
  • 三星手機換電池視頻教程,三星2016換電池教程
  • 機械設計制造畢業設計題目,機械專業夾具類畢業設計題目匯總/組合機床、車床撥叉、飛錘支架、連接座、倒擋撥叉、蓋、法蘭盤、銅襯軸套、心軸零件、曲軸箱零件、托板、發動
  • Shell基礎(四):字符串截取及切割、字符串初值的處理、基使用Shell數組、expect預期交互、使用正則表達式...
  • shell編程入門,shell基礎之04
  • 計算機基礎知識試題及答案(全),計算機序列類型和字典試題,計算機考試試題和資料
  • 新開店鋪怎么做推廣,淘寶新開店鋪沒有生意不會推廣的苦衷與心得
  • 如何注冊商標,給大家科普一下商標小知識沒注冊下來的商標,做吊牌,做包裝袋,發朋友圈廣告時千萬不能打R。將未注冊商標冒充注冊商標使用的,或者使用未注冊商標的,最高
  • 商標繳費后多久初步審核通過,商標注冊需要多久下證
  • 商標買賣,信用百度公司商標信息爬取
  • 商標檢索網站,中國商標網 -爬蟲
  • 應用商店上架app容易么,iOS App 上架App Store及提交審核(Appuploader)
  • app證書失效了怎么辦,iOS證書申請打包上傳App Store審核完整流程(7個步驟)
  • 銀行合并后,10萬億同業存款免繳存準 全面降準將推遲
  • kindle買8g還是32g,萬字長文!對比分析了多款存儲方案,KeeWiDB最終選擇自己來
  • java中的final關鍵字有哪些用法,Java: static,final,代碼塊 的詳解
  • 服務器反應慢及解決辦法,Linux服務器 大量的CLOSE_WAIT、TIME_WAIT解決辦法
  • wait for的用法,oracle for update wait 解析
  • 如何手動關閉close_wait,CLOSE_WAIT和TIME_WAIT
  • 渲染軟件哪個好用,Windows平臺OpenGL渲染視頻
  • 怎樣說代碼讓人聽不懂,RPA初級認證直通車,不懂代碼也能成為技術大佬
  • java快速開發平臺 開源,快上車!Java技術開發大廠直通車馬上啟動!
  • 架構師培訓,Java高級:java架構師成長直通車pan
  • 【淘寶開店教程】淘寶直通車常見問題講解
  • 《java架構師成長直通車》課程階段一學習筆記
  • 視頻教程-Java面試Offer直通車-Java