Java基礎知識

冷暖不知 發表於 2020-09-23

Java語言規範、API、JDK、IDE的含義:Java語言規範是Java語法和語義技術性定義,API是應用程式介面(Java預定義類和介面),Java開發工具包(JDK)包含軟體庫、編譯器、直譯器以及其他工具,整合開發環境(IDE)提供編輯、編譯、除錯和線上幫助功能。Java平臺版本:Java SE:允許開發和部署在桌面、伺服器和嵌入式環境和實時環境中使用的Java應用程式。Java EE:它幫助開發和部署可移植、健壯、可伸縮且安全的伺服器端Java應用程式。Java EE是在Java SE的基礎上構建的,它提供web服務、元件模型、管理和通訊API。Java ME:它為在移動裝置和嵌入式裝置上執行的應用程式提供一個健壯且靈活的環境。Java執行環境Java的目的碼可以在任何平臺上執行,Java的原始碼編譯之後生成.class檔案,由位元組碼構成(比如部落格之前安卓逆向研究的Dalvik位元組碼)。位元組碼可以在任何裝有Java虛擬機器的計算機上執行,Java虛擬機器是一個用於解釋位元組碼的軟體。Java程式剖析:註釋:Java程式包含三種註釋,即多行註釋、單行註釋、文件註釋,多行註釋,
/* 註釋內容
註釋內容
/
單行註釋://
文件註釋:可以用javadoc提取註釋,形成文件,
/** 註釋內容
*/修飾符:常見如public, protected, private, static, abstract, final,用於指定資料、方法、類的屬性以及它們的用法。類:是Java的基本結構,一個程式可以包含一個或多個類,一個Java原始檔裡最多隻有一個公有類。main方法:Java直譯器通過呼叫main方法執行應用程式。常量:一旦初始化後就不能再改變的資料,語法為final datatype CONSTANT_NAME = value;Java資料型別Java資料型別:包括基本型別和引用型別,
基本型別包括 整數型別(byte, short, int, long) 字元型別(char)浮點型別(float, double)邏輯型別(boolean);
引用型別包括 類,介面,陣列。
其中,浮點數中以d或D結尾或者無字尾表示double型別,以f或F結尾的表示float型別;整數字面值中以l或L結尾的表示long型別,其他表示int型別。Java數值型別轉換:
如果有一個運算元是double型別,另一個運算元轉換為double 型別;否則,如果有一個運算元是float型別,另一個運算元轉換為float型別;否則,如果有一個運算元是long型別,另一個運算元轉換為long型別;否則,兩個運算元都轉換為int型別;資料轉換總是向較大範圍的資料型別轉換,避免精度損失。
將值賦值給較大取值範圍的變數時,自動進行型別轉換;
將值賦值給較小取值範圍的變數時,必須使用強制型別轉換。字元資料型別:char表示16位的單個Unicode字元,char型別的字面值 包括以兩個單引號界定的單個Unicode字元,可以用\uxxxx形式表示的, 轉義字元表示\n \t \b \r \f \ ` " 。程式設計風格:良好的程式設計風格有利於減少錯誤,產生容易閱讀、易於理解的程式碼。類和方法前使用文件註釋,方法步驟前使用行註釋;變數和方法名使用小寫,如果有多個單詞,第一個單詞首字母小寫,其他單詞首字母大寫;類名的每個單詞的首字母大寫;常量使用大寫,單詞間以下劃線分割。Java常見錯誤型別:包括語法錯誤,即在編譯期間產生的錯誤;執行時錯誤,導致程式非正常終止的錯誤;邏輯錯誤,程式不能按預期的方式執行,編譯不會報錯。條件語句:包括If語句、switch語句、條件表示式,其中的if語句判斷條件必須是boolean型別的;在if-else條件語句中,else語句與同一塊中最近的if語句匹配。在使用條件語句中,避免在條件表示式中使用比較操作符判斷布林變數的真假。
switch語句的判斷條件expression的計算結果只能是byte, char, short, int。value1-valueN必須與 判斷條件型別相同,且為常量表示式,不能是變數。Java中常用的數學函式:Math.random方法生成[0.0,1.0)之間的double型別的隨機數,可以用它寫出簡單的表示式來生成任意範圍的隨機數,一般地,a + (int)(Math.random() * b)返回[a, a+b);還可以用該方法生成隨機字元,Java中每個字元對應一個Unicode編碼從0000到FFFF,在生成一個隨機字元,就是產生一個0到65535之間的隨機數,所以計算的表示式為(int)(Math.random() * (65535+1))。生成任意2個字元ch 1和ch2(ch1 < ch2)之間的隨機字元,
(char)(ch1 + (int)(Math.random() * (ch2 - ch1 + 1)))字元資料型別和操作在字元型資料和數值型別資料之間轉換時,如果轉換結果適用於目標變數(不會有精度損失),可以採用隱式轉換;否則必須使用強制型別轉換。所有數值運算子都可以用在char型運算元上,如果另一個運算元是數值或字元,那麼char型運算元就自動轉換為數值;如果另一個運算元是字串,那麼char型運算元就會自動轉換成字串再和另外一個運算元字串相連。字串型別String型別是不可變的,其內容是不可修改的;如以下程式碼片段:String s = “java”;
s = “HTML”;
12其中s可以理解為一個物件指標,其指向物件空間,其中的字串為java,第二句賦值只是將s指向了另一個物件空間。equals方法用於比較兩個字串是否包含相同的內容。equalsIngoreCase忽略大小寫比較內容是否相同。regionMatch比較部分內容是否相同。startsWith判斷是否以某個字串開始。endsWith判斷是否以某個字串結束。compareTo方法用於比較兩個字串的大小,即第一個不同字元的差值.呼叫length()方法可以獲取字串的長度。。charAt(index)方法可以獲取指定位置的字元,index必須位於0到s.length()-1之間。concat()方法用於連線兩個字串,連線操作返回一個新的字串。indexOf返回字串中字元或字串匹配的位置,返回-1表示未找到。indexOf指定第二個參數列示從指定的位置開始查詢。toCharArray將字串轉換成字元陣列。valueOf方法將基本資料型別轉換為字串,例如轉化為字串,如
String s1 = String.valueOf(1.0); String s2 = String.valueOf(true);;字串轉換為基本資料型別,Double.parseDouble(str)等。方法:方法簽名指方法名稱、引數型別、引數數量和返回型別;==一個類中不能包含簽名相同或僅返回型別不同的多個方法;==方法頭中宣告的變數稱為形參,形參可以使用final修飾,表示方法內部不允許修改該引數;形參不允許有預設值,最後一個可為變長引數。方法可以有返回值,建構函式沒有返回值。如果方法宣告中含有形參,呼叫方法時必須提供實參,實參的型別必須與形參的型別相容:如父類形參可用子類實參。呼叫方法時,基本資料型別的實參值的副本被傳遞給方法的形參,方法內部對形參的修改不影響實參值;物件型別的引數是引用呼叫。方法過載:方法過載是指方法名稱相同,但方法簽名不同的方法,僅返回型別不同不可過載。一個類中可以包含多個過載的方法。當呼叫方法時,Java編譯器會根據實參的個數和型別尋找最準確的方法進行呼叫;呼叫時匹配的方法多於一個,則會產生編譯錯誤,成為歧義呼叫。陣列:陣列是引用型別。多維陣列只是陣列的陣列,故陣列元素也可能是引用型別變數凡使用new後,記憶體單元都初始化為0或Null。宣告陣列引用變數,datatype[] arrayRefVar;,任何例項化的陣列都是Object的子類。陣列變數是引用型別的變數,宣告陣列變數並不分配記憶體空間,必須通過new例項化來分配記憶體空間。新建立的陣列其元素根據型別被初始化為預設的初始值, 數值型別為0字元型別為’\u0000’布林型別為false引用型別為null陣列可以在宣告的括號後提供初始值,double[] mylist = {1.9, 2.9, 3, 3.5};或者double[] mylist = new double[]{1.9, 2.9, 3, 3.5};陣列的大小在建立這個陣列之後不能被改變,arrayRefVar.length可以訪問陣列的長度。直接使用賦值語句不能實現陣列複製,結果是兩個陣列引用變數指向同一個陣列物件。在將陣列作為實參傳遞給方法時,修改形參引用的陣列,將改變實參引用的陣列。JVM將陣列儲存在叫堆的記憶體區域裡,陣列引用儲存在棧空間中。String傳遞給方法:由於實參的字元序列不可修改,將克隆給形參。可以把型別相同,但個數可變的引數傳遞給方法,方法中的引數宣告為typeName…parameterName,==Java將可變長引數當陣列看待,通過length屬性得到可變引數的個數。print(String…args){ //可看作String[] args
for(String temp: args)
System.out.println(temp);
System.out.println(args.length);
}
12345java.util.Arrays類包括各種靜態方法,其中實現了陣列的排序和查詢,即sort方法與binarySearch方法。二維陣列的每個元素(陣列)的長度可以不同,建立二維不規則陣列時,可以只指定第一維下標,第一維的每個元素為null, 必須為每個元素使用new建立陣列。物件導向思考:類間的關係描述方法,關聯關係:是一種通用的二元關係,物件間通過活動發生聯絡,例如學生選學課程,教師教授課程。==在Java中,關聯關係可以用資料域或方法來實現,對於方法,一個類中的方法包含另一個類作為引數。聚合關係是一種擁有關係,表示整體與部分之間的關係,即Has-a的關係,在聚合關係中,一個物件可以被多個聚集著擁有; 組合關係是一種隸屬關係,一個從屬者只能被一個聚集著擁有。如一個Name物件只能為一個Person所擁有,但一個Address物件可以被多個Person所共享。繼承關係,表示子類與父類之間的is-a關係,通過繼承,子類可以重用父類的資料和程式碼。實現關係,表示介面和類之間的關係,類實現介面。繼承:繼承是一種軟體重用,如果沒有繼承,會出現很多重複定義。語法為:class ClassName extends Superclass{
classbody
}
123子類繼承了父類中可訪問的資料域和方法,子類也可新增新的資料域和方法,子類不繼承符類的建構函式。
一個子類只能有一個直接父類:單繼承。
子類繼承的父類的私有屬性不能訪問,但是可以通過所繼承的get和set公有方法設定和訪問。當第一次建立子類物件時,首先初始化其父類靜態成員變數(如果沒有父類物件),然後初始化當前子類物件的靜態成員變數。注意:第一次之後建立子類物件時,不會再次初始化父類和子類的靜態成員變數。其實,靜態成員變數在有任何例項變數物件之前已經存在。
接著執行該子類物件的父類的建構函式super(…),可能是編譯為父類提供的預設無參建構函式super()。然後執行子類例項變數定義時的初始化表示式,若定義時未給出初始值,則預設為0或null.最後執行子類建構函式中super(…)後面的語句。super關鍵字:super呼叫父類的建構函式,必須是子類建構函式的第一條且僅一條語句(先構造父類),如果子類建構函式中沒有顯示地呼叫父類的建構函式,那麼將自動呼叫父類不帶引數的建構函式。 如果父類屬性或方法可以在子類訪問,則使用super.data或者super.method(parameters)進行訪問。super與無參建構函式:如果一個類自定義了建構函式(不管有無引數),系統不會自動加上無參建構函式; 反之,如果沒定義則會加上。編譯在為子類新增無參建構函式時,用super()預設呼叫父類的無參建構函式,如果找不到父類的無參建構函式,則子類新增無參建構函式失敗。 所以,如果一個類定義了帶引數的建構函式,一定別忘了定義一個無參建構函式。例項方法覆蓋如果子類重新定義了從父類中繼承的例項方法,稱為方法覆蓋。僅當方法是
可訪問的例項方法
時,才能被覆蓋,即私有例項方法不能被覆蓋,私有方法自動視為final. (final修飾類時表示其不可被繼承;修飾方法表示不可在子類中被重寫;修飾成員變數時表示只能在宣告處或者建構函式中初始化一次)。靜態方法不能被覆蓋,如果靜態方法在子類中重新定義,那麼父類方法將被隱藏。一旦父類中的方法被覆蓋,則不能通過引用的子類物件訪問被覆蓋的父類方法。在子類類體函式中可以使用super引用被覆蓋的父類方法。隱藏和覆蓋的區別:覆蓋,子類物件被父類引用變數引用,父類引用變數呼叫的相同簽名的函式是子類函式(不能發現父類函式,晚期繫結);隱藏,同上,但父類引用變數訪問的是父類變數、函式(可以在發現)。子類方法同樣可以與父類中可訪問的方法構成過載。多型和動態繫結:過載發生在編譯時,編譯時編譯器根據方法簽名找到最合適的方法;多型發生在執行時,執行時JVM根據變數所引用的物件的真正型別來找到最合適的例項方法。多型是晚期繫結,繫結是指找到函式的入口地址的過程。訪問控制符和修飾符final成員修飾符本類本包子類它包publicyyyyprotectedyyyn無(package)yynnprivateynnn父類私有成員在子類不可見;父類公有和保護成員在子類可見繼承到子類後不改變父類成員的訪問許可權。
異常處理:一般而言,帶有異常處理的程式會寫成try…catch的形式;在try體內完成程式的正常處理流程,在catch體內完成異常處理。若正常的異常處理出現錯誤,則使用"throw <異常物件引用>"丟擲異常;丟擲的異常由catch捕獲,未被捕獲的異常逐層傳播到main,如果main也沒有處理該異常,則作業系統會終止main執行。丟擲而未捕獲(未處理)異常的函式,必須用throws宣告其未處理的這些異常。有些異常是系統丟擲的,程式只需要捕獲處理即可。異常的捕獲順序:無論何時,throw以後的語句都不會執行;無論同層catch是否捕獲、處理本層的異常(即使丟擲或轉發異常),同層的finally總是都會執行。 一個catch捕獲到異常後,同層catch都不會執行,然後執行同層finally; 一個同層try-catch-finally結束,若無異常則執行其後語句,若有異常,則跳過其後語句,進入上層catch流程。

上圖中紅色標出的為div的執行軌跡。自定義異常類:自定義異常類必須繼承Throwable或其子類;自定義異常類通常繼承Exception及其子類,因為它是程式可處理的類。自定義異常類會在父類的基礎上增加成員變數,因此,通常需要覆蓋toString函式(經常被列印)。未增加新成員就沒有必要自定義異常類。自定義異常類通常不必定義clone, equals:捕獲和處理異常時通常只是引用異常物件而已。抽象類:Java可定義不含方法體的方法,其方法體由子類根據具體情況實現,這樣的方法稱為抽象方法,包括抽象方法的類必須是抽象類。抽象類和抽象方法的宣告必須加上abstract關鍵字。類C如果滿足下面任一條件,則該類包含抽象方法且是抽象類: 類C顯示地進行一個抽象方法的宣告;類C的父類中宣告的抽象方法未在類C和它的父類中實現;類C的介面中宣告一個方法,並且類C未實現該方法;只有類C有一個為實現的方法,類C就是抽象類。抽象類不能被例項化,即不能用new關鍵字建立物件;抽象類可以定義建構函式,可以被子類呼叫;具體子類必須實現抽象父類中所有抽象方法,否則子類需要宣告為抽象類;抽象類只能用具體子類的物件例項化。介面:介面是公共靜態常量,公共靜態方法和公共抽象方法,預設例項方法的集合。介面中的一切都預設是public的,沒有修飾符的方法預設是abstract的,資料成員預設是static的。介面不能定義建構函式,一個介面可繼承extends多個介面,介面不能被類extends,一個類可實現implements多個介面。public interface I1{
public static final int k = 1;
public abstract void m();
}
1234等價於:public interface I1{
int k = 1; //=1不可省略,因為預設是public static final的,必須初始化
void m(); //不可定義函式體,預設是public abstract.
}
1234介面中的方法通過“介面型別的引用變數.方法名”呼叫,但介面型別的引用變數必須引用實現了該介面的具體類的例項物件。
介面中的常量名通過"介面名.常量名"訪問。