Java核心語法
一:Java基礎
1:Java有什麼優勢
Java適合於寫軟體,有封裝、繼承、多型、跨平臺(生成.class檔案,二進位制級別)的優點。
2:基本名詞
(1):JVM 虛構一個計算機,通過在實際的計算機上模擬模擬實現各種計算機的功能。JVM遮蔽了與具體作業系統平臺相關的資訊,使得Java程式只需生成在JVM上可以執行的目的碼(位元組碼),所以可以不加修改的在多個系統上執行。
(2):JDK Java開發工具包,是Java的核心,包括了JRE、Java工具、Java基礎類庫。
(3):JRE Java的執行環境(可能會問JDK和JRE的區別)。
(4):GCJava中的垃圾回收機制,不必擔心記憶體洩漏。
3:OOP(面向物件程式設計)
(1):繼承Java中沒有多繼承,要用介面(一個類可以實現多個介面)或者間接繼承實現;子類會繼承父類所有非私有屬性和方法。
(2):向上轉型父類引用可以指向子類物件,父類引用無法呼叫子類的非重寫方法(父類是子類的,子類的不是父類的);介面引用可以指向實現類物件,介面引用無法呼叫實現類的非重寫方法。
(3):過載與重寫
a. 過載:在同一個類的內部,函式名相同但是引數列表不一樣(引數的個數不一樣或者引數的型別不一樣)的多個方法就構成了過載方法。
b. 重寫:在子類中擁有與父類同名的方法。只有遵循了“兩同兩小一大”規則的方法才構成重寫。
“兩同”指的是方法名相同,形參列表相同;
“兩小”指的是子類方法的返回值應該比父類方法的返回值型別相同或者更小,子類方法宣告丟擲的異常型別應該比父類丟擲的異常更小或者相同;
“一大”指的是子類方法的訪問許可權應該比父類的訪問許可權相等或者更大
(4):this和super的用法
a. this關鍵字:是自身的一個物件,代表物件本身,可以理解為指向物件本身的一個指標,必須在非靜態方法中使用(因為靜態方法屬於類,而非示例物件)
b. super關鍵字:可以理解為是指向自己超(父)類物件的一個指標,而這個超類指的是離自己最近的一個父類;呼叫父類中的某一個建構函式(應該為建構函式中的第一條語句);子類與父類的成員變數同名,引用成員變數。
(5):介面和抽象類的區別
抽象類是單繼承,介面是多重實現。
介面中無構造方法,抽象類可有構造方法。
在抽象類中,可以有自己的資料成員,也可以有非 abstract的成員方法;而在介面方式的實現中,只能有static final資料成員(不過在interface中一般不定義資料成員),所有的成員方法都是abstract的。
介面的方法都是public的,但抽象類可以有protected或是private的方法。
(6):staticstatic關鍵字可以修飾成員變數和方法,來讓它們變成類的所屬,而不是物件的所屬
呼叫方式:static可以使用"類名.成員"來呼叫;
儲存位置:static成員是所有物件的共享資料,儲存在方法區(共享資料區)的靜態區;普通成員儲存在堆記憶體的物件中;
生存週期:static成員隨著類的載入而存在隨著類的消失而消失,而普通成員隨著物件建立和回收而存在和釋放;
靜態使用時需要注意的事項:
1.靜態方法只能訪問靜態成員。(非靜態既可以訪問靜態,又可以訪問非靜態);
2.靜態方法中不可以使用this或者super關鍵字【this和super屬於物件】。
靜態程式碼塊:隨著類的呼叫或建立例項而執行,而且只執行一次。用於給類進行初始化。
(7):final
A. 被final修飾的類,不能被子類繼承。【因此一個類不能既被abstract宣告,又被final宣告】;
B. 被final修飾的方法,在使用的過程中不能被修改,只能使用,即不能方法重寫;
C. 被宣告為final的變數必須在宣告時給出變數的初始值,使用的過程中不能被修改,只能讀取。
二:編碼規範
1:命名
變數和方法名駝峰命名法,第一個單詞的字母全部小寫,從第二個單詞開始首字母大寫其他字元小寫
2:文件註釋
(1)開頭處:說明作者、時間、版本、要實現的功能的描述等資訊
/**
*類的功能說明
*@author he
*@version 1.0
*@since JDK1.0
*/
(2):方法註釋
/**
*這個方法是輸出......
*@param 對變數進行說明
*@return 對返回值進行說明
*@throws 對丟擲的異常的型別進行說明
*/
(3):生成文件註釋
通過Javadoc工具,可以很方便的將原始碼中的註釋轉換為HTML文件說明。
操作步驟:在project下找到generate javadoc,在configure中加入JDK下bin裡的javadoc.exe路徑,即可生成在選定目錄。
3:快捷鍵的使用
Eclipse的編輯功能非常強大,掌握了Eclipse快捷鍵功能,能夠大大提高開發效率。Eclipse中有如下一些和編輯相關的快捷鍵。
1)【ALT+/】當記不全類、方法和屬性的名字時,多體驗一下【ALT+/】快捷鍵帶來的好處吧。
2) 【Ctrl+/】快速添加註釋,能為游標所在行或所選定行快速添加註釋或取消註釋。
3)【Ctrl+D】刪除當前行,不用為刪除一行而按那麼多次的刪除鍵。
4)【Ctrl+Shift+B】在當前行設定斷點或取消設定的斷點。
三:JDK API
1:經常使用的庫
為維護和使用方便,類庫按包結構劃分經常使用的包:
(1)java.lang 基礎庫,如字串、多執行緒等,使用頻率高,不用匯入包。
(2)java.io 檔案操作、輸入輸出。
(3)java.util 常用工具包,如集合,隨機數產生器,日曆,時鐘。
(4)java.net 網路操作。
(5)java.security 安全相關操作(明文傳輸比較危險)。
(6)java.text 處理文字、日期、數字、資訊的格式。
(7)java.sql 資料庫訪問。
2:核心API
(1)日期操作
a. Date以及常用API
Java中的時間:使用標準類庫的Date類表示,是用距離一個固定的時間點(UTC時間1970年1月1日00:00:00)的毫秒數(可正可負,long型別的)表達特定的時間點。
Date類簡介:java.util.Date類封裝日期以及時間資訊,常用方法為setTime以及getTime,Date類的大多數用於進行時間分量計算的方法已經被Calendar取代。
Date date = new Date();
//獲取系統當前時間以及時間資訊
long time = date.getTime();
//從1970年1月1日到現在所經過的毫秒數,long型別
b. SimpleDateFormat
java.text.SimpleDateFormat是一個以跟語言環境有關的方式來格式化和解析日期的具體類。這個類允許進行格式化日期文字,也允許解析文字日期和規範化
構造方法:
SimpleDateFormat()
SimpleDateFormat(String pattern) 用給定的模式和預設語言環境的日期格式符號構造 SimpleDateFormat方法
final String format(Date date) Date->String
Date parse(String source) throws ParseException String->Date
將String格式化為Date:
String str="2012-12-12";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(str);
println(date);
c. Calendar類: java.util.Calendar類是用於封裝日曆資訊,其主要作用在於其方法可以對時間分量進行計算
Calendar是抽象類,其具體子類需要針對不同國家不同地區的日曆系統。其中應用最廣泛的是GregorianCalendar(格里高裡歷,也就是通用的陽曆),對應世界上絕大多數國家以及地區使用的標準日曆系統。
getInstance方法:該方法獲取Calendar型別的一個通用物件,該方法返回一個Calendar物件,其日曆欄位已經由當前日期和時間初始化。
Calendar c = Calendar.getInstance();
GregorianCalendar c1 = new GregorianCalendar(2017,Calendar.March,...) //月份要用類裡面定義的靜態常量
int getActualMaximum(int field) 給定次Calendar的時間值,返回指定日曆欄位可能擁有的最大值
(2)集合操作
Collection:在實際開發中,需要將使用的物件儲存於特定的資料結構的容器中。JDK就提供了這樣的容器--Collection(集合)。
Collection是一個介面,定義了集合相關的操作方法,其有兩個子介面:List和Set。
List:可重複集, Set:不可重複集(呼叫equals()方法比較的結果判斷元素是否重複)。
java.util中共有13個類可用於管理集合物件,它們支援集、列表或對映等集合,以下是這些類的簡單介紹
a.集合Set:
HashSet: 使用HashMap的一個集的實現。雖然集定義成無序,但必須存在某種方法能相當高效地找到一個物件。使用一個HashMap物件實現集的儲存和檢索操作是在固定時間內實現的。
TreeSet: 在集中以升序對物件排序的集的實現。這意味著從一個TreeSet物件獲得第一個迭代器將按升序提供物件。TreeSet類使用了一個TreeMap。
b.列表List:
Vector: 實現一個類似陣列一樣的表,可自動增加容量。使用下標儲存和檢索物件就象在一個標準的陣列中一樣,也可以用一個迭代器從一個Vector中檢索物件。Vector是唯一的同步容器類,當兩個或多個執行緒同時訪問時也是效能良好的。
Stack: 這個類從Vector派生而來,並且增加了方法實現棧。
LinkedList: 實現一個連結串列。由這個類定義的連結串列也可以像棧或佇列一樣被使用。
ArrayList: 實現一個數組,它的規模可變並且能像連結串列一樣被訪問。它提供的功能類似Vector類但不同步。
【知識點:ArrayList和LinkedList的區別】
1.ArrayList是實現了基於動態陣列的資料結構,LinkedList是基於連結串列結構。
2.對於get和set方法,ArrayList要優於LinkedList,因為LinkedList要移動指標。
3.對於add和remove,LinkedList比較佔優勢,因為ArrayList要移動資料。
c.對映map:
Hashtable:所有的鍵必須非空。為了能高效的工作,定義鍵的類必須實現hashcode()方法和equal()方法。這個類 是前面java實現的一個繼承,並且通常能在實現映象的其他類中更好的使用。
HashMap: 允許儲存空物件,而且允許鍵是空。
ConcurrentHashMap:
WeakHashMap: 實現這樣一個映象:通常如果一個鍵對一個物件而言不再被引用,鍵/物件對將被捨棄。這與HashMap形成對照,映象 中的鍵維持鍵/物件對的生命週期,儘管使用映象的程式不再有對鍵的引用,並且因此不能檢索物件。
TreeMap: 實現這樣一個映象,物件是按鍵升序排列的。
【知識點:HashMap和Hashtable有什麼區別?】
HashMap允許鍵和值是null,而Hashtable則不允許鍵或者值是null。
Hashtable是同步的,而HashMap不是,所以HashMap更適用於單執行緒環境,Hashtable則適用於多執行緒環境。
四:字串
1:String
String為不可變物件(字串一旦被建立,物件永遠無法被改變,但是字串引用可以重新賦值)。
(1) String常量池:java為了提高效能,將所有靜態字串(字面量、常量、常量連線的結果)在常量池中建立,並儘量使用同一物件,重用靜態字串。對於重複出現的字串,JVM首先在常量池中查詢,如果存在則返回物件。
(2) 記憶體編碼:採用unicode編碼,任一字元對應兩個位元組的定長編碼(可以表示中文)。
(3) 常用API :
a.判斷字元內容是否相同
boolean equals(str):複寫了object類中的equals方法。
boolean.equalsIgnorecase(str):判斷內容是否相同,並忽略大小寫。
compareTo(str) :按字典序比較兩個字串,返回第一個不相同字元的字典序之差。
== 比較的是地址,而非內容;equals比較的是內容。
b. 型別轉換
將字元陣列轉成字串:
建構函式:String(char[])
String(char[],offset,count) 將字元陣列中的一部分轉成字串
靜態方法:
static String copyValueOf(char[]);
static String copyValueOf(char[] data,int offset,int count);將字元陣列中的一部分轉成字串。
將字串轉成字元組:
char[] tocharArray();
將位元組陣列轉成字串:
String(byte[])
String(byte[],offset,count):將位元組陣列中的一部分轉成字串。
將字串轉成位元組陣列:
byte[] getBytes()
將基本資料型別轉成字串:
static String valueOf(int/double),呼叫時可直接用String.valueOf(number)
2:StringBuffer和StringBuilder
String為不可變物件(字串一旦被建立,物件永遠無法被改變,但是字串引用可以重新賦值),而StringBuffer和StringBuilder封裝可變字串,需要修改字串時用。兩者的用法相似,區別在於StringBuilder執行緒不安全,但速度快,而StringBuffer可使用在多執行緒中。
StringBuffer類中的方法主要偏重於對於字串的變化,例如追加、插入和刪除等,這個也是StringBuffer和String類的主要區別。
【知識點:java string物件 “+”和append連結兩個字串之間的差異】
String +號拼接的原理是會在底層new一個StringBuilder,重新開闢一段記憶體,再呼叫append操作,而StringBuilder和StringBuffer直接append,效率比String的+高得多。
public StringBuffer append(各種型別的資料 ):追加內容到當前StringBuffer物件的末尾,類似於字串的連線。
public StringBuffer deleteCharAt(int index) : 刪除指定位置的字元,然後將剩餘的內容形成新的字串。
注意:StringBuilder的很多方法的返回值均為StringBuilder型別,方法的返回語句均為:return this;由於返回的都是當前物件,所以會在程式中看到一種簡潔的書寫方式:
str.append("softi").append("java").insert(1,"oracle").replace(0,4,"softi.com");
五:類
1:Object類
(1)概念:在Java的繼承中,java.lang.Object類位於繼承的頂端,如果定義一個Java類時沒有使用extends關鍵字宣告其父類,則其父類預設為java.lang.Object。Object型別的引用變數可以指向任何型別物件。
(2)toString方法:原則上建議每個類都重寫toString方法,格式上大多數遵循"類的名字[域值]",如果不重寫,將使用Object類的toString方法,其返回值為:類名@雜湊碼。
Object類中的toString方法返回物件值得字串表示;
Java中很多地方會預設呼叫物件的toString方法:字串+物件 自動呼叫物件的toString方法;System.out.print(任意物件) ,會自動呼叫物件的toString方法;
toString方法是非常有用的除錯工具。JDK中的標準類庫中,許多類都定義了toString方法,方便使用者獲取相關物件狀態的必要資訊。
(3)equals方法: Object類中的的equals方法用於檢測一個物件是否等同於另一個物件,在Object類中,這個方法判斷兩個物件是否具有相同的引用,即是否指向相同的物件。
在實際應用中,一般也需要重寫該方法,通過比較物件的成員屬性,使該方法更有意義。
2:包裝類
(1)概念
Java中的八種基本資料型別byte,char,short,int,float,long,double,boolean都是以值的方式保存於記憶體中,而不是儲存在物件中。它們不是Object的子類,所以不能參與面向物件的開發。包裝類(wrapper)就是用來將基本資料型別轉換成相應物件的一種特殊類。包裝類是不可改變的類,在構造了包裝類物件之後,不允許更改包裝在其中的值。包裝類是final的,所以不可以有子類。
基本型別 包裝類 父類
int java.lang.Integer Number
long Long Number
double Double ...
short Short
float Float
byte Byte
char Charcter Object
boolean Boolean Object
(2)用法
Number類及其主要方法:抽象類Number是Integer,Long,Double,Short,Float,Byte類的父類,Number類的子類必須提供將表示的數值轉換成對應的型別的方法。
intValue() 以int的形式返回指定的數值。
Integer常用方法:
該類提供了int型別和String型別之間進行轉換的方法,並且提供了一些常量。
static int MAX_VALUE 2^31 - 1的常量,表示int型別的最大值。
static int MIN_VALUE -2^31。
Double常用方法:
構造方法:
Double(double value)
Double(String s)
常用方法:
double doubleValue() 返回此物件的double值;
static double parseDouble(String s) 返回一個新的double值,該值被初始化為指定的String表示的值;
Double.parseDouble("123.54")
Double.parseDouble("¥123.54") 這麼呼叫時會丟擲NumberFormatException異常
(3)自動裝箱以及自動拆箱操作(autoboxing)
該功能是從Java5.0之後加入的,自動裝箱和拆箱是JDK5的編譯器在編譯器的“預處理”階段進行的工作
Integer a = 100;//裝箱
Integer b = 200;
Integer c = a + b;//拆箱然後裝箱
裝箱跟拆箱是編譯器進行的工作,而不是JVM。編譯器會在生成類的位元組碼時會插入必要的方法呼叫:Integer a = 100 =>Integer a = Integer.valueOf(100);
注意:當包裝類作為方法的引數時,eg:void takeNumber(Integer i){ },實際呼叫該方法時傳遞Integer型別或者int型別的引數都可以。
六:異常
異常分類: 可查異常(自己捕捉),執行時異常(陣列越界、除0等,不是必須進行捕捉)和錯誤(系統級別的異常)3種。
【知識點:throw和throws的區別,Error和Exception的區別】
執行時異常與非執行時異常的區別:執行時異常是不可查異常,不需要進行顯式的捕捉;非執行時異常是可查異常,必須進行顯式的捕捉,或者丟擲。