Java 中这些常用关键字,总有那么些被你遗忘的
??點擊上方?好好學java?,選擇?星標?公眾號
重磅資訊、干貨,第一時間送達 今日推薦:2 個月的面試親身經歷告訴大家,如何進入 BAT 等大廠?我們知道 Java 中是有保留關鍵字的,到目前為止大約有 50+ 關鍵字,具體如下:
在命名上我們不能與這些關鍵字沖突,有沖突的話,編譯器會報錯。每個關鍵字都有特定的場景。當然 Java 現在有 50+ 關鍵字,我們不可能每個都用的到, 所以這里我挑出了 8 個常用的或者比較重要的關鍵字,一起來學習或者復習一下。
1、static
static 翻譯成靜態的、全局的,一旦被修飾,說明被修飾的東西在一定范圍內是共享的。
static 只能修飾類變量、方法和方法塊,你沒見過 static 修飾類的吧。
「當 static 修飾類變量時」,如果該變量是 public 的話,表示該類變量可以被任何類直接訪問,而且無需初始化類,直接使用 類名.變量名 這種形式直接訪問。比如:
public?class?StaticDemo?{//?被?static?修飾的變量static?String?str?=?"我被?static?修飾了";public?static?void?main(String[]?args)?{System.out.println(StaticDemo.str);} }「static 修飾變量時,需要需要考慮線程安全問題」,因為多個線程同時操作一個共享變量時,極有可能出現并發問題。如我們定義了:public static List<String> list = new ArrayLis t(); 這樣的共享變量。這個 list 如果同時被多個線程訪問的話,就有線程安全的問題。
「當 static 修飾方法時」,那就是說,無需本類的對象即可調用此方法,參考項目中的 utils 類。聲明為 static 的方法有以下幾條限制:
僅能調用其他的 static 方法.
它們只能訪問 static 成員.
它們不能以任何方式引用this或super.
static方法獨立于任何實例,因此static方法必須被實現,而不能是抽象的abstract.
「static 方法內部的變量在執行時是沒有線程安全問題的」。方法執行時,數據運行在棧里面,棧的 數據每個線程都是隔離開的,所以不會有線程安全的問題。
「當 static 修飾方法塊時」,我們叫做靜態塊,靜態塊常常用于在類啟動之前,初始化一些值,靜態代碼塊語法格式:
????static?{}靜態代碼塊跟普通代碼塊最大的不同是加載時間。靜態代碼塊的內容是在類加載的時候執行的,「而且只會加載一次」。
2、final
final 的意思是不變的,一般來說用于以下三種場景:
「1.修飾類」,被 final 修飾的類,表明該類是無法繼承的;比如我們常用的 string 類。
「2.修飾方法」,被 final 修飾的方法,表明該方法是無法覆寫的;
「3.修飾變量」, 被 final 修飾的變量,說明該變量在聲明的時候,就必須初始化完成,而且以后也不能修改其內存地址。
對于第三點需要注意一下,說的是無法修改其內存地址,并沒有說無法修改其值。因為對于 List、 Map 這些集合類來說,被 final 修飾后,是可以修改其內部值的,但卻無法修改其初始化時的內存地址。
3、this
在 Java 程序中遍地都是 this 的使用,this 使得程序設計變得規范、簡單、靈活。但是在使用過程中,在不同場合它的含義并不完全相同,使用不當還會出現錯誤。
「this 就是指針/引用」,在Java語言中,當創建一個對象后,Java虛擬機就會為其分配一個指向對象本身的指針,這個指針就是“this”。
看看 this 在不同場合下的使用:
「1、this 調用本類中的成員變量」
public?class?ThisDemo?{String?name;public?void?fun(String?name)?{this.name?=?name;} }此時this指當前對象的引用,既然是對象的引用,我們也可以通過this調用成員方法.
「2、this 調用構造方法」
public?class?ThisDemo?{public?ThisDemo(String?s)?{System.out.println(s);}public?ThisDemo()?{this("調用構造方法");}public?static?void?main(String[]?args)?{new?ThisDemo();} }在一個Java類中,構造方法是一個與類同名的方法,必須與類的名字相同。而且在Java類中必須存在一個構造方法。如果在代碼中沒有顯示的體現構造方法的話,那么編譯器在編譯的時候會自動添加.(如果你手動添加了一個構造方法,那么編譯器就不會在為你自動添加無參的構造方法) .我們在實際編程的時候有時候需要在一個構造方法中對另一個構造方法進行調用。因此我們可以使用this()代表構造方法,但是,在使用this關鍵字調用其他構造方法的時候,this()調用構造方法只能放在構造方法的首行,為的是能夠為類中的屬性初始化;而且至少有一個構造方法是不用this調用,否則程序會出現錯誤。
「3、this 引用當前對象」
this 最重要的特定就是表示當前對象(注意是當前對象和當前對象的引用區分開),那什么叫當前對象呢?在Java中當前對象就是指當前正在調用類中方法的對象。使用this引用當前對象是指如果在類的方法中需要返回一個對象,并且該對象是方法所在的類的當前對象,可以使用this關鍵字作為方法的返回值。例如:
public?class?ThisDemo?{public?ThisDemo()?{}public?ThisDemo?getThis()?{return?this;}public?static?void?main(String[]?args)?{ThisDemo?t1?=?new?ThisDemo();ThisDemo?t2?=?t1.getThis();System.out.println(t1?==?t2);System.out.println(t1.equals(t2));//輸出//true//true} }4、synchronized
synchronized 常用于并發編程中,用來控制線程對變量、方法的訪問,從而解決并發問題。
在 java 代碼中使用 synchronized 可是使用在代碼塊和方法中,根據Synchronized 用的位置可以有這些使用場景:
圖片描述synchronized 的位置不同,鎖住的對象也不一樣,有以下幾種情況:
當synchronized作用在方法上時,鎖住的便是對象實例(this);
當作用在靜態方法時鎖住的便是對象對應的Class實例,因為 Class數據存在于永久代,因此靜態方法鎖相當于該類的一個全局鎖;
當synchronized作用于某一代碼域時,鎖住的便是對應的代碼塊。
5、volatile
volatile 關鍵字也是常用在并發編程中,用來保證共享變量的可見性。因為在 JVM 和系統內存交互中,存在一個緩存層,如果變量沒有被 volatile 修飾的話,修改后的變量值會存入到緩存中,等待系統刷新到內存中。這樣會導致一些并發問題,被 volatile 修飾的變量,如果對變量進行修改的話,會被 CPU 強制刷新到內存中,其他使用該變量的線程可以第一時間看到變量最新的值。
「volatile 還有一個作用就是阻止重排序」,有時候編譯器會對代碼進行優化,選擇一個它認為最高效的執行方式,但是有時候會帶來一些問題,可以研究單例模式的雙重檢測鎖寫法。
6、try、catch、finally
其實這是三個關鍵字,我把它組合在一起,因為在使用時我們也是組合使用,try、catch、finally 常用于我們捕捉異常的一整套流程,先來看看三個關鍵字的職責:
「try」:用來確定代碼執行的范圍;
「catch」:捕捉可能會發生的異常;
「finally」:用來執行一定要執行的代碼塊,比如關閉連接;
這個關鍵字組合使用到沒什么難的,但是這里會有一個面試中常用的面試題:「如果發生了異常,finally 會不會執行」?
對于這個問題,我們用事實說話,看下面這個例子:
public?static?void?main(String[]?args)?{try?{System.out.println("try?運行中");int?n?=?1?/?0;}?catch?(Exception?e)?{System.out.println("catch?運行中");throw?new?RuntimeException("報錯了");}?finally?{System.out.println("finally?運行中");} }運行結果如下:
從結果中可以看出,「先執行了 finally 中的內容,在拋出 catch 中的異常」。
7、transient
這個關鍵字你咋一看可能會覺得陌生,但是它在很多類中應用廣泛。
「transient 關鍵字是用來阻止序列化的」,被 transient 關鍵字修飾的變量,在序列化時會被忽略掉。
我們可以在 ArrayList 的源碼中找到 transient 的身影,ArrayList 中的 elementData 變量就是被 transient 修飾的;
transient?Object[]?elementData;?//?non-private?to?simplify?nested?class?access思考題:「為什么 ArrayList 要用 transient 修飾 elementData 變量?」
8、 default
default 在代碼中也是比較常見的,比如 switch 分支一句中,用來表示默認實現或者操作。
default 也會用在接口的方法上。我們知道接口的實現類必須實現接口的所有方法,但是有時候我們一個接口類中,有那么幾個方法是大部分實現類公用的,那么我們就可以加上 default ,在接口中實現該方法,子類就可以不用實現了。
public?class?StaticDemo?{public?static?void?main(String[]?args)?{Test?test?=?new?Test();test.test();}}interface?TestApi{default?void?test(){System.out.println("我是默認實現,子類類可以不用實現了.....");} } class?Test?implements?TestApi{}最后,再附上我歷時三個月總結的?Java 面試 + Java 后端技術學習指南,這是本人這幾年及春招的總結,目前,已經拿到了騰訊等大廠offer,拿去不謝,github 地址:https://github.com/OUYANGSIHAI/JavaInterview
這么辛苦總結,給個star好不好。?點擊閱讀原文,直達
總結
以上是生活随笔為你收集整理的Java 中这些常用关键字,总有那么些被你遗忘的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个 http 请求的曲折经历
- 下一篇: 我的大学到研究生自学 Java 之路,过