JavaSE高階【吐血整理彙總】
阿新 • • 發佈:2018-12-20
1. Object類、常用API
1.1 Object類
- java.lang.Object
- 類 Object 是類層次結構的根(父)類。
- 每個類(Person,Student…)都使用 Object 作為超(父)類。
- 所有物件(包括陣列)都實現這個類的方法。
1.1.1 Object類equals方法
- Person類預設繼承了Object類,所以可以使用Object類的equals方法
- boolean equals(Object obj) 指示其他某個物件是否與此物件“相等”。
- equals方法原始碼:
public boolean equals(Object obj) { return (this == obj); }
- 引數:
- Object obj:可以傳遞任意的物件
- == 比較運算子,返回的是一個布林值 true false
- 基本資料型別:比較的是值
- 引用資料型別:比價的是兩個物件的地址值
- this是誰?那個物件呼叫的方法,方法中的this就是那個物件;p1呼叫的equals方法所以this就是p1
- obj是誰?傳遞過來的引數p2
- this == obj --> p1 == p2
1.1.2 Object類equals方法防止空指標異常
- Objects類的equals方法:對兩個物件進行比較,防止空指標異常
public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }
1.2 Date類
- long getTime() 把日期轉換為毫秒值(相當於System.currentTimeMillis()方法)
- 返回自 1970 年 1 月 1 日 00:00:00 GMT 以來此 Date 物件表示的毫秒數。
- Date類的帶引數構造方法
- Date(long date) :傳遞毫秒值,把毫秒值轉換為Date日期
- Date類的空引數構造方法
- Date() 獲取當前系統的日期和時間
1.2.1 DateFormat類成員方法
- java.text.DateFormat:是日期/時間格式化子類的抽象類
- 作用:
格式化(也就是日期 -> 文字)、解析(文字-> 日期) - 成員方法:
String format(Date date) 按照指定的模式,把Date日期,格式化為符合模式的字串
Date parse(String source) 把符合模式的字串,解析為Date日期 - DateFormat類是一個抽象類,無法直接建立物件使用,可以使用DateFormat類的子類
- 作用:
- java.text.SimpleDateFormat extends DateFormat
- 構造方法:
SimpleDateFormat(String pattern)
用給定的模式和預設語言環境的日期格式符號構造 SimpleDateFormat。 - 引數:
String pattern:傳遞指定的模式
模式:區分大小寫的
字元 中文 y 年 M 月 d 日 H 時 m 分 s 秒 - 寫對應的模式,會把模式替換為對應的日期和時間
“yyyy-MM-dd HH:mm:ss” - 注意:
- 模式中的字母不能更改,連線模式的符號可以改變
- “yyyy年MM月dd日 HH時mm分ss秒”
- 構造方法:
1.2.2 DateFormat類parse方法
- 使用DateFormat類中的方法parse,把文字解析為日期
- 使用步驟:
- 建立SimpleDateFormat物件,構造方法中傳遞指定的模式
- 呼叫SimpleDateFormat物件中的方法parse,把符合構造方法中模式的字串,解析為Date日期
- 注意:
- public Date parse(String source) throws ParseException
- parse方法聲明瞭一個異常叫ParseException
- 如果字串和構造方法的模式不一樣,那麼程式就會丟擲此異常
- 呼叫一個丟擲了異常的方法,就必須的處理這個異常,要麼throws繼續丟擲這個異常,要麼try catch自己處理
1.2.3 DateFormat類format方法
- 使用DateFormat類中的方法format,把日期格式化為文字
- 使用步驟:
- 建立SimpleDateFormat物件,構造方法中傳遞指定的模式
- 呼叫SimpleDateFormat物件中的方法format,按照構造方法中指定的模式,把Date日期格式化為符合模式的字串(文字)
1.3 Calendar類
- java.util.Calendar類:日曆類
- Calendar類是一個抽象類,裡邊提供了很多操作日曆欄位的方法(YEAR、MONTH、DAY_OF_MONTH、HOUR )
- Calendar類無法直接建立物件使用,裡邊有一個靜態方法叫getInstance(),該方法返回了Calendar類的子類物件
- static Calendar getInstance() 使用預設時區和語言環境獲得一個日曆。
1.3.1 Calendar類成員方法
- Calendar類的常用成員方法:
- public int get(int field):返回給定日曆欄位的值。
- public void set(int field, int value):將給定的日曆欄位設定為給定值。
- public abstract void add(int field, int amount):根據日曆的規則,為給定的日曆欄位新增或減去指定的時間量。
- public Date getTime():返回一個表示此Calendar時間值(從曆元到現在的毫秒偏移量)的Date物件。
- 成員方法的引數:
- int field:日曆類的欄位,可以使用Calendar類的靜態成員變數獲取
- public static final int YEAR = 1; 年
- public static final int MONTH = 2; 月
- public static final int DATE = 5; 月中的某一天
- public static final int DAY_OF_MONTH = 5;月中的某一天
- public static final int HOUR = 10; 時
- public static final int MINUTE = 12; 分
- public static final int SECOND = 13; 秒
- int field:日曆類的欄位,可以使用Calendar類的靜態成員變數獲取
1.4 陣列
- public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):
將陣列中指定的資料拷貝到另一個數組中。- 引數:
- src - 源陣列。
- srcPos - 源陣列中的起始位置(起始索引)。
- dest - 目標陣列。
- destPos - 目標資料中的起始位置。
- length - 要複製的陣列元素的數量。
- 引數:
- 練習:
- 將src陣列中前3個元素,複製到dest陣列的前3個位置上
- 複製元素前:
src陣列元素[1,2,3,4,5],dest陣列元素[6,7,8,9,10] - 複製元素後:
src陣列元素[1,2,3,4,5],dest陣列元素[1,2,3,9,10]
- 複製元素前:
- 將src陣列中前3個元素,複製到dest陣列的前3個位置上
1.5 StringBuilder類
- java.lang.StringBuilder類:字串緩衝區,可以提高字串的效率
- 構造方法:
- StringBuilder()
構造一個不帶任何字元的字串生成器,其初始容量為 16 個字元。 - StringBuilder(String str)
構造一個字串生成器,並初始化為指定的字串內容。
- StringBuilder()
1.5.1 StringBuilder常用方法
- public StringBuilder append(…):
新增任意型別資料的字串形式,並返回當前物件自身。
1.5.2 StringBuilder和String相互轉換
- String->StringBuilder:可以使用StringBuilder的構造方法
- StringBuilder(String str) 構造一個字串生成器,並初始化為指定的字串內容。
- StringBuilder->String:可以使用StringBuilder中的toString方法
- public String toString():將當前StringBuilder物件轉換為String物件。
1.6 裝箱與拆箱
- 裝箱:把基本型別的資料,包裝到包裝類中(基本型別的資料->包裝類)
- 構造方法:
- Integer(int value) 構造一個新分配的 Integer 物件,它表示指定的 int 值。
- Integer(String s) 構造一個新分配的 Integer 物件,它表示 String 引數所指示的 int 值。
- 傳遞的字串,必須是基本型別的字串,否則會丟擲異常 “100” 正確 “a” 拋異常
- 靜態方法:
- static Integer valueOf(int i) 返回一個表示指定的 int 值的 Integer 例項。
- static Integer valueOf(String s) 返回儲存指定的 String 的值的 Integer 物件。
- 構造方法:
- 拆箱:在包裝類中取出基本型別的資料(包裝類->基本型別的資料)
- 成員方法:
- int intValue() 以 int 型別返回該 Integer 的值。
- 成員方法:
1.6.1 自動裝箱與自動拆箱
- 基本型別的資料和包裝類之間可以自動的相互轉換
- JDK1.5之後出現的新特性
1.6.2 基本型別與字串型別相互轉換
- 基本型別->字串(String)
- 基本型別的值+"" 最簡單的方法(工作中常用)
- 包裝類的靜態方法toString(引數),不是Object類的toString() 過載
static String toString(int i) 返回一個表示指定整數的 String 物件。 - String類的靜態方法valueOf(引數)
static String valueOf(int i) 返回 int 引數的字串表示形式。
- 字串(String)->基本型別
- 使用包裝類的靜態方法parseXXX(“字串”);
- Integer類: static int parseInt(String s)
- Double類: static double parseDouble(String s)
- 使用包裝類的靜態方法parseXXX(“字串”);
2. Collection、泛型
2.1 Collection
- java.util.Collection介面
- 所有單列集合的最頂層的介面,裡邊定義了所有單列集合共性的方法
- 任意的單列集合都可以使用Collection介面中的方法
- 共性的方法:
- public boolean add(E e) : 把給定的物件新增到當前集合中 。
- public void clear() : 清空集合中所有的元素。
- public boolean remove(E e) : 把給定的物件在當前集合中刪除。
- public boolean contains(E e) : 判斷當前集合中是否包含給定的物件。
- public boolean isEmpty() : 判斷當前集合是否為空。
- public int size() : 返回集合中元素的個數。
- public Object[] toArray() : 把集合中的元素,儲存到陣列中。
2.2 迭代器
- java.util.Iterator介面:迭代器(對集合進行遍歷)
- 有兩個常用的方法
- boolean hasNext() 如果仍有元素可以迭代,則返回 true。
判斷集合中還有沒有下一個元素,有就返回true,沒有就返回false - E next() 返回迭代的下一個元素。
取出集合中的下一個元素
- boolean hasNext() 如果仍有元素可以迭代,則返回 true。
- Iterator迭代器,是一個介面,我們無法直接使用,需要使用Iterator介面的實現類物件,獲取實現類的方式比較特殊
- Collection介面中有一個方法,叫iterator(),這個方法返回的就是迭代器的實現類物件
Iterator iterator() 返回在此 collection 的元素上進行迭代的迭代器。
- 有兩個常用的方法
- 迭代器的使用步驟(重點):
- 使用集合中的方法iterator()獲取迭代器的實現類物件,使用Iterator介面接收(多型)
- 使用Iterator介面中的方法hasNext判斷還有沒有下一個元素
- 使用Iterator介面中的方法next取出集合中的下一個元素
2.3 增強for
- 增強for迴圈:底層使用的也是迭代器,使用for迴圈的格式,簡化了迭代器的書寫
- 是JDK1.5之後出現的新特性
- Collectionextends Iterable : 所有的單列集合都可以使用增強for
- public interface Iterable實現這個介面允許物件成為 “foreach” 語句的目標。
- 增強for迴圈:用來遍歷集合和陣列
- 格式:
for(集合/陣列的資料型別 變數名: 集合名/陣列名){ sout(變數名); }
- 格式:
2.4 泛型
- 建立集合物件,使用泛型
- 好處:
- 避免了型別轉換的麻煩,儲存的是什麼型別,取出的就是什麼型別
- 把執行期異常(程式碼執行之後會丟擲的異常),提升到了編譯期(寫程式碼的時候會報錯)
- 弊端:
- 泛型是什麼型別,只能儲存什麼型別的資料
- 好處:
2.4.1 泛型利弊
- 建立集合物件,不使用泛型
- 好處:
- 集合不使用泛型,預設的型別就是Object型別,可以儲存任意型別的資料
- 弊端:
- 不安全,會引發異常
- 好處:
2.4.2 泛型的萬用字元
- ?:代表任意的資料型別
- 使用方式:
- 不能建立物件使用
- 只能作為方法的引數使用
- 定義一個方法,能遍歷所有型別的ArrayList集合
- 這時候我們不知道ArrayList集合使用什麼資料型別,可以泛型的萬用字元?來接收資料型別
- 注意 : 泛型沒有繼承概念的
2.4.3 泛型的上下限定
- 泛型的上限限定: ? extends E 代表使用的泛型只能是E型別的子類/本身
- 泛型的下限限定: ? super E 代表使用的泛型只能是E型別的父類/本身
2.4.4 含有泛型的類
- 定義一個含有泛型的類,模擬ArrayList集合
- 泛型是一個未知的資料型別,當我們不確定什麼什麼資料型別的時候,可以使用泛型
- 泛型可以接收任意的資料型別,可以使用Integer,String,Student…
- 建立物件的時候確定泛型的資料型別
2.4.5 含有泛型的介面1
- 含有泛型的介面,第一種使用方式:定義介面的實現類,實現介面,指定介面的泛型
public interface Iterator<E> { E next(); }
- Scanner類實現了Iterator介面,並指定介面的泛型為String,所以重寫的next方法泛型預設就是String
public final class Scanner implements Iterator<String>{ public String next() {} }
2.4.6 含有泛型的介面2
- 含有泛型的介面第二種使用方式:介面使用什麼泛型,實現類就使用什麼泛型,類跟著介面走
- 就相當於定義了一個含有泛型的類,建立物件的時候確定泛型的型別
public interface List<E>{ boolean add(E e); E get(int index); }
public class ArrayList<E> implements List<E>{ public boolean add(E e) {} public E get(int index) {} }
2.4.7 含有泛型的方法
- 定義含有泛型的方法:泛型定義在方法的修飾符和返回值型別之間
- 格式:
修飾符 <泛型> 返回值型別 方法名(引數列表(使用泛型)){ 方法體; }
- 含有泛型的方法,在呼叫方法的時候確定泛型的資料型別
- 傳遞什麼型別的引數,泛型就是什麼型別
3. List、Set
3.1 List介面
- java.util.List介面 extends Collection介面
- List介面的特點:
- 有序的集合,儲存元素和取出元素的順序是一致的(儲存123 取出123)
- 有索引,包含了一些帶索引的方法
- 允許儲存重複的元素
- List介面中帶索引的方法(特有)
- public void add(int index, E element): 將指定的元素,新增到該集合中的指定位置上。
- public E get(int index):返回集合中指定位置的元素。
- public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
- public E set(int index, E element):用指定元素替換集合中指定位置的元素,返回值的更新前的元素。
- 注意:
- 操作索引的時候,一定要防止索引越界異常
- IndexOutOfBoundsException:索引越界異常,集合會報
- ArrayIndexOutOfBoundsException:陣列索引越界異常
- StringIndexOutOfBoundsException:字串索引越界異常
- List介面的特點:
3.1.1 LinkedList集合
- java.util.LinkedList集合 implements List介面
-
LinkedList集合的特點:
- 底層是一個連結串列結構:查詢慢,增刪快
- 裡邊包含了大量操作首尾元素的方法
注意:使用LinkedList集合特有的方法,不能使用多型
public void addFirst(E e):將指定元素插入此列表的開頭。 public void addLast(E e):將指定元素新增到此列表的結尾。 public void push(E e):將元素推入此列表所表示的堆疊。 public E getFirst():返回此列表的第一個元素。 public E getLast():返回此列表的最後一個元素。 public E removeFirst():移除並返回此列表的第一個元素。 public E removeLast():移除並返回此列表的最後一個元素。 public E pop():從此列表所表示的堆疊處彈出一個元素。 public boolean isEmpty():如果列表不包含元素,則返回true。
-
3.2 Set介面
- java.util.Set介面 extends Collection介面
- Set介面的特點:
- 不允許儲存重複的元素
- 沒有索引,沒有帶索引的方法,也不能使用普通的for迴圈遍歷
- Set介面的特點:
- java.util.HashSet集合 implements Set介面
- HashSet特點:
- 不允許儲存重複的元素
- 沒有索引,沒有帶索引的方法,也不能使用普通的for迴圈遍歷
- 是一個無序的集合,儲存元素和取出元素的順序有可能不一致
- 底層是一個雜湊表結構(查詢的速度非常的快)
- HashSet特點:
3.2.1 LinkedHashSet集合
- java.util.LinkedHashSet集合 extends HashSet集合
- LinkedHashSet集合特點:
底層是一個雜湊表(陣列+連結串列/紅黑樹)+連結串列:多了一條連結串列(記錄元素的儲存順序),保證元素有序
- LinkedHashSet集合特點:
- 雜湊值
- 是一個十進位制的整數,由系統隨機給出(就是物件的地址值,是一個邏輯地址,是模擬出來得到地址,不是資料實際儲存的實體地址)
- 在Object類有一個方法,可以獲取物件的雜湊值
- int hashCode() 返回該物件的雜湊碼值。
- hashCode方法的原始碼:
- public native int hashCode();
- native:代表該方法呼叫的是本地作業系統的方法
- 可變引數:
- 是JDK1.5之後出現的新特性
- 使用前提:
- 當方法的引數列表資料型別已經確定,但是引數的個數不確定,就可以使用可變引數.
- 使用格式:定義方法時使用
- 修飾符 返回值型別 方法名(資料型別…變數名){}
- 可變引數的原理:
- 可變引數底層就是一個數組,根據傳遞引數個數不同,會建立不同長度的陣列,來儲存這些引數
- 傳遞的引數個數,可以是0個(不傳遞),1,2…多個
3.3 Collections工具類
- java.utils.Collections是集合工具類,用來對集合進行操作。部分方法如下:
- public static boolean addAll(Collection c, T… elements):往集合中新增一些元素。
- public static void shuffle(List<?> list) 打亂順序:打亂集合順序。
3.3.1 Collections排序
- java.utils.Collections是集合工具類,用來對集合進行操作。部分方法如下:
- public static void sort(List list):將集合中元素按照預設規則排序。
- 注意:
- sort(List list)使用前提
被排序的集合裡邊儲存的元素,必須實現Comparable,重寫介面中的方法compareTo定義排序的規則
- sort(List list)使用前提
- Comparable介面的排序規則:
自己(this)-引數:升序
3.3.2 Collections排序比較
- java.utils.Collections是集合工具類,用來對集合進行操作。部分方法如下:
- public static void sort(List list,Comparator<? super T> ):將集合中元素按照指定規則排序。
- Comparator和Comparable的區別
- Comparable:自己(this)和別人(引數)比較,自己需要實現Comparable介面,重寫比較的規則compareTo方法
- Comparator:相當於找一個第三方的裁判,比較兩個
- Comparator的排序規則:
- o1-o2:升序
4. Map
4.1 Map
- java.util.Map<k,v>集合
- Map集合的特點:
- Map集合是一個雙列集合,一個元素包含兩個值(一個key,一個value)
- Map集合中的元素,key和value的資料型別可以相同,也可以不同
- Map集合中的元素,key是不允許重複的,value是可以重複的
- Map集合中的元素,key和value是一一對應
- Map集合的特點:
- java.util.HashMap<k,v>集合 implements Map<k,v>介面
- HashMap集合的特點:
- HashMap集合底層是雜湊表:查詢的速度特別的快
- JDK1.8之前:陣列+單向連結串列
- JDK1.8之後:陣列+單向連結串列|紅黑樹(連結串列的長度超過8):提高查詢的速度
- hashMap集合是一個無序的集合,儲存元素和取出元素的順序有可能不一致
- HashMap集合底層是雜湊表:查詢的速度特別的快
- HashMap集合的特點:
- java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合
- LinkedHashMap的特點:
- LinkedHashMap集合底層是雜湊表+連結串列(保證迭代的順序)
- LinkedHashMap集合是一個有序的集合,儲存元素和取出元素的順序是一致的
- LinkedHashMap的特點:
4.1.1 keySet()
- Map集合的第一種遍歷方式:通過鍵找值的方式
- Map集合中的方法:
Set keySet() 返回此對映中包含的鍵的 Set 檢視。 - 實現步驟:
- 使用Map集合中的方法keySet(),把Map集合所有的key取出來,儲存到一個Set集合中
- 遍歷set集合,獲取Map集合中的每一個key
- 通過Map集合中的方法get(key),通過key找到value
- Map集合中的方法:
4.1.2 entrySet()
- Map集合遍歷的第二種方式:使用Entry物件遍歷
- Map集合中的方法:
Set<Map.Entry<K,V>> entrySet() 返回此對映中包含的對映關係的 Set 檢視。 - 實現步驟:
- 使用Map集合中的方法entrySet(),把Map集合中多個Entry物件取出來,儲存到一個Set集合中
- 遍歷Set集合,獲取每一個Entry物件
- 使用Entry物件中的方法getKey()和getValue()獲取鍵與值
- Map集合中的方法:
4.1.3 自定義型別鍵值
- HashMap儲存自定義型別鍵值
- Map集合保證key是唯一的:
- 作為key的元素,必須重寫hashCode方法和equals方法,以保證key唯一
- Map集合保證key是唯一的:
4.2 LinkedHashMap
- java.util.LinkedHashMap<K,V> entends HashMap<K,V>
- Map 介面的雜湊表和連結列表實現,具有可預知的迭代順序。
- 底層原理:
雜湊表+連結串列(記錄元素的順序)
4.3 Hashtable
- java.util.Hashtable<K,V>集合 implements Map<K,V>介面
- Hashtable:底層也是一個雜湊表,是一個執行緒安全的集合,是單執行緒集合,速度慢
- HashMap:底層是一個雜湊表,是一個執行緒不安全的集合,是多執行緒的集合,速度快
- HashMap集合(之前學的所有的集合):可以儲存null值,null鍵
- Hashtable集合,不能儲存null值,null鍵
- Hashtable和Vector集合一樣,在jdk1.2版本之後被更先進的集合(HashMap,ArrayList)取代了
- Hashtable的子類Properties依然活躍在歷史舞臺
- Properties集合是一個唯一和IO流相結合的集合
JDK9的新特性—集合介面新增多元素
- List介面,Set介面,Map介面:裡邊增加了一個靜態的方法of,可以給集合一次性新增多個元素
- static List of(E… elements)
- 使用前提:
- 當集合中儲存的元素的個數已經確定了,不在改變時使用
- 注意:
- of方法只適用於List介面,Set介面,Map介面,不適用於接介面的實現類
- of方法的返回值是一個不能改變的集合,集合不能再使用add,put方法新增元素,會丟擲異常
- Set介面和Map介面在呼叫of方法的時候,不能有重複的元素,否則會丟擲異常
Debug除錯程式
- 可以讓程式碼逐行執行,檢視程式碼執行的過程,除錯程式中出現的bug
- 使用方式:
- 在行號的右邊,滑鼠左鍵單擊,新增斷點(每個方法的第一行,哪裡有bug新增到哪裡)
- 右鍵,選擇Debug執行程式
- 程式就會停留在新增的第一個斷點處
- 執行程式:
- f8:逐行執行程式
- f7:進入到方法中
- shift+f8:跳出方法
- f9:跳到下一個斷點,如果沒有下一個斷點,那麼就結束程式
- ctrl+f2:退出debug模式,停止程式
- Console:切換到控制檯
5. 異常
5.1 Throwable類
- java.lang.Throwable:類是 Java 語言中所有錯誤或異常的超類。
- Exception:編譯期異常,進行編譯(寫程式碼)java程式出現的問題
- RuntimeException:執行期異常,java程式執行過程中出現的問題
- 異常就相當於程式得了一個小毛病(感冒,發燒),把異常處理掉,程式可以繼續執行(吃點藥,繼續革命工作)
- Error:錯誤
- 錯誤就相當於程式得了一個無法治癒的毛病(非典,艾滋).必須修改原始碼,程式才能繼續執行
- Exception:編譯期異常,進行編譯(寫程式碼)java程式出現的問題
5.2 throws關鍵字
- throws關鍵字:異常處理的第一種方式,交給別人處理
- 作用:
- 當方法內部丟擲異常物件的時候,那麼我們就必須處理這個異常物件
- 可以使用throws關鍵字處理異常物件,會把異常物件宣告丟擲給方法的呼叫者處理(自己不處理,給別人處理),最終交給JVM處理–>中斷處理
- 使用格式:在方法宣告時使用
修飾符 返回值型別 方法名(引數列表) throws AAAExcepiton,BBBExcepiton...{ throw new AAAExcepiton("產生原因"); throw new BBBExcepiton("產生原因"); ... }
- 注意:
- throws關鍵字必須寫在方法宣告處
- throws關鍵字後邊宣告的異常必須是Exception或者是Exception的子類
- 方法內部如果丟擲了多個異常物件,那麼throws後邊必須也宣告多個異常
如果丟擲的多個異常物件有子父類關係,那麼直接宣告父類異常即可 - 呼叫了一個宣告丟擲異常的方法,我們就必須的處理宣告的異常
要麼繼續使用throws宣告丟擲,交給方法的呼叫者處理,最終交給JVM
要麼try…catch自己處理異常
5.3 try…catch
- try…catch:異常處理的第二種方式,自己處理異常
- 格式:
try{ 可能產生異常的程式碼 }catch(定義一個異常的變數,用來接收try中丟擲的異常物件){ 異常的處理邏輯,異常異常物件之後,怎麼處理異常物件 一般在工作中,會把異常的資訊記錄到一個日誌中 } ... catch(異常類名 變數名){ }
- 注意:
- try中可能會丟擲多個異常物件,那麼就可以使用多個catch來處理這些異常物件
- 如果try中產生了異常,那麼就會執行catch中的異常處理邏輯,執行完畢catch中的處理邏輯,繼續執行try…catch之後的程式碼
- 如果try中沒有產生異常,那麼就不會執行catch中異常的處理邏輯,執行完try中的程式碼,繼續執行try…catch之後的程式碼
5.4 finally程式碼塊
- 格式:
try{ 可能產生異常的程式碼 }catch(定義一個異常的變數,用來接收try中丟擲的異常物件){ 異常的處理邏輯,異常異常物件之後,怎麼處理異常物件 一般在工作中,會把異常的資訊記錄到一個日誌中 } ... catch(異常類名 變數名){ }finally{ 無論是否出現異常都會執行 }
- 注意:
- finally不能單獨使用,必須和try一起使用
- finally一般用於資源釋放(資源回收),無論程式是否出現異常,最後都要資源釋放(IO)
5.5 子父類的異常
- 如果父類丟擲了多個異常,子類重寫父類方法時,丟擲和父類相同的異常或者是父類異常的子類或者不丟擲異常。
- 父類方法沒有丟擲異常,子類重寫父類該方法時也不可丟擲異常。此時子類產生該異常,只能捕獲處理,不能宣告丟擲
- 注意 : 父類異常時什麼樣,子類異常就什麼樣
5.6 自定義異常類
- java提供的異常類,不夠我們使用,需要自己定義一些異常類
- 格式:
public class XXXExcepiton extends Exception | RuntimeException{ 新增一個空引數的構造方法 新增一個帶異常資訊的構造方法 }
- 注意:
- 自定義異常類一般都是以Exception結尾,說明該類是一個異常類
- 自定義異常類,必須的繼承Exception或者RuntimeException
繼承Exception:那麼自定義的異常類就是一個編譯期異常,如果方法內部丟擲了編譯期異常,就必須處理這個異常,要麼throws,要麼try…catch
- 繼承RuntimeException:那麼自定義的異常類就是一個執行期異常,無需處理,交給虛擬機器處理(中斷處理)
6. 執行緒、同步
- 主執行緒 : 執行主(main)方法的執行緒
- 單執行緒程式:java程式中只有一個執行緒
- 執行從main方法開始,從上到下依次執行
- JVM執行main方法,main方法會進入到棧記憶體
- JVM會找作業系統開闢一條main方法通向cpu的執行路徑
- cpu就可以通過這個路徑來執行main方法
- 而這個路徑有一個名字,叫main(主)執行緒
6.1 多執行緒建立方式一
- 建立多執行緒程式的第一種方式:建立Thread類的子類
- java.lang.Thread類:是描述執行緒的類,我們想要實現多執行緒程式,就必須繼承Thread類
- 實現步驟:
- 建立一個Thread類的子類
- 在Thread類的子類中重寫Thread類中的run方法,設定執行緒任務(開啟執行緒要做什麼?)
- 建立Thread類的子類物件
- 呼叫Thread類中的方法start方法,開啟新的執行緒,執行run方法
void start() 使該執行緒開始執行;Java 虛擬機器呼叫該執行緒的 run 方法。
結果是兩個執行緒併發地執行;當前執行緒(main執行緒)和另一個執行緒(建立的新執行緒,執行其 run 方法)。
多次啟動一個執行緒是非法的。特別是當執行緒已經結束執行後,不能再重新啟動。
- java程式屬於搶佔式排程,那個執行緒的優先順序高,那個執行緒優先執行;同一個優先順序,隨機選擇一個執行
6.1.1 執行緒的名稱
- 主執行緒: main
- 新執行緒: Thread-0,Thread-1,Thread-2
6.1.2 獲取執行緒的名稱
- 使用Thread類中的方法getName()
- String getName() 返回該執行緒的名稱。
- 可以先獲取到當前正在執行的執行緒,使用執行緒中的方法getName()獲取執行緒的名稱
- static Thread currentThread() 返回對當前正在執行的執行緒物件的引用。
6.1.3 設定執行緒的名稱
- 使用Thread類中的方法setName(名字)
- void setName(String name) 改變執行緒名稱,使之與引數 name 相同。
- 建立一個帶引數的構造方法,引數傳遞執行緒的名稱;呼叫父類的帶參構造方法,把執行緒名稱傳遞給父類,讓父類(Thread)給子執行緒起一個名字
- Thread(String name) 分配新的 Thread 物件。
6.1.4 執行緒睡眠
- public static void sleep(long millis) :
使當前正在執行的執行緒以指定的毫秒數暫停(暫時停止執行)。
毫秒數結束之後,執行緒繼續執行
6.2 多執行緒建立方式二
- 建立多執行緒程式的第二種方式:實現Runnable介面
- java.lang.Runnable
- Runnable 介面應該由那些打算通過某一執行緒執行其例項的類來實現。類必須定義一個稱為 run 的無引數方法。
- java.lang.Thread類的構造方法
- Thread(Runnable target) 分配新的 Thread 物件。
- Thread(Runnable target, String name) 分配新的 Thread 物件。
- java.lang.Runnable
- 實現步驟:
- 建立一個Runnable介面的實現類
- 在實現類中重寫Runnable介面的run方法,設定執行緒任務
- 建立一個Runnable介面的實現類物件
- 建立Thread類物件,構造方法中傳遞Runnable介面的實現類物件
- 呼叫Thread類中的start方法,開啟新的執行緒執行run方法
- 實現Runnable介面建立多執行緒程式的好處:
- 避免了單繼承的侷限性
- 一個類只能繼承一個類(一個人只能有一個親爹),類繼承了Thread類就不能繼承其他的類
- 實現了Runnable介面,還可以繼承其他的類,實現其他的介面
- 增強了程式的擴充套件性,降低了程式的耦合性(解耦)
- 實現Runnable介面的方式,把設定執行緒任務和開啟新執行緒進行了分離(解耦)
- 實現類中,重寫了run方法:用來設定執行緒任務
- 建立Thread類物件,呼叫start方法:用來開啟新執行緒
- 避免了單繼承的侷限性
6.3 匿名內部類方式建立執行緒
- 匿名:沒有名字
- 內部類:寫在其他類內部的類
- 匿名內部類作用:簡化程式碼
- 把子類繼承父類,重寫父類的方法,建立子類物件合一步完成
- 把實現類實現類介面,重寫介面中的方法,建立實現類物件合成一步完成
- 匿名內部類的最終產物:子類/實現類物件,而這個類沒有名字
- 格式:
new 父類/介面(){ 重複父類/介面中的方法 };
- 格式:
6.4 執行緒安全問題-同步程式碼塊
- 解決執行緒安全問題的一種方案:使用同步程式碼塊
- 格式:
synchronized(鎖物件){ 可能會出現執行緒安全問題的程式碼(訪問了共享資料的程式碼) }
- 注意:
- 通過程式碼塊中的鎖物件,可以使用任意的物件
- 但是必須保證多個執行緒使用的鎖物件是同一個
- 鎖物件作用:
把同步程式碼塊鎖住,只讓一個執行緒在同步程式碼塊中執行
6.5 執行緒安全問題-同步方法
- 解決執行緒安全問題的二種方案:使用同步方法
- 使用步驟:
- 把訪問了共享資料的程式碼抽取出來,放到一個方法中
- 在方法上新增synchronized修飾符
- 格式:定義方法的格式
修飾符 synchronized 返回值型別 方法名(引數列表){ 可能會出現執行緒安全問題的程式碼(訪問了共享資料的程式碼) }
6.6 執行緒安全問題-Lock鎖
- 解決執行緒安全問題的三種方案:使用Lock鎖
- java.util.concurrent.locks.Lock介面
- Lock 實現提供了比使用 synchronized 方法和語句可獲得的更廣泛的鎖定操作。
- Lock介面中的方法:
- void lock()獲取鎖。
- void unlock() 釋放鎖。
- java.util.concurrent.locks.ReentrantLock implements Lock介面
- 使用步驟:
- 在成員位置建立一個ReentrantLock物件
- 在可能會出現安全問題的程式碼前呼叫Lock介面中的方法lock獲取鎖
- 在可能會出現安全問題的程式碼後呼叫Lock介面中的方法unlock釋放鎖
6.7 執行緒間通訊
- 等待喚醒案例:執行緒之間的通訊
- 建立一個顧客執行緒(消費者):告知老闆要的包子的種類和數量,呼叫wait方法,放棄cpu的執行,進入到WAITING狀態(無限等待)
- 建立一個老闆執行緒(生產者):花了5秒做包子,做好包子之後,呼叫notify方法,喚醒顧客吃包子
- 注意:
- 顧客和老闆執行緒必須使用同步程式碼塊包裹起來,保證等待和喚醒只能有一個在執行
- 同步使用的鎖物件必須保證唯一
- 只有鎖物件才能呼叫wait和notify方法
- Obejct類中的方法
- void wait()
在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法前,導致當前執行緒等待。 - void notify()
喚醒在此物件監視器上等待的單個執行緒。
會繼續執行wait方法之後的程式碼
- void wait()
6.7.1 計時等待的兩種方式
- 進入到TimeWaiting(計時等待)有兩種方式
- 使用sleep(long m)方法,在毫秒值結束之後,執行緒睡醒進入到Runnable/Blocked狀態
- 使用wait(long m)方法,wait方法如果在毫秒值結束之後,還沒有被notify喚醒,就會自動醒來,執行緒睡醒進入到Runnable/Blocked狀態
- 喚醒的方法:
- void notify() 喚醒在此物件監視器上等待的單個執行緒。
- void notifyAll() 喚醒在此物件監視器上等待的所有執行緒。
6.7.2 資源類
- 資源類:包子類
- 設定包子的屬性
- 皮
- 陷
- 包子的狀態: 有 true,沒有 false
- 設定包子的屬性
6.7.3 生產者類
- 生產者(包子鋪)類 : 是一個執行緒類,可以繼承Thread
- 設定執行緒任務(run):生產包子
- 對包子的狀態進行判斷
- true:有包子
- 包子鋪呼叫wait方法進入等待狀態
- false:沒有包子
- 包子鋪生產包子
- 增加一些趣味性:交替生產兩種包子
- 有兩種狀態(i%2==0)
- 包子鋪生產好了包子
- 修改包子的狀態為true有
- 喚醒吃貨執行緒,讓吃貨執行緒吃包子
- true:有包子
- 注意:
- 包子鋪執行緒和包子執行緒關係–>通訊(互斥)
- 必須同時同步技術保證兩個執行緒只能有一個在執行
- 鎖物件必須保證唯一,可以使用包子物件作為鎖物件
- 包子鋪類和吃貨的類就需要把包子物件作為引數傳遞進來
- 需要在成員位置建立一個包子變數
- 使用帶引數構造方法,為這個包子變數賦值
6.7.4 消費者類
- 消費者(吃貨)類:是一個執行緒類,可以繼承Thread
- 設定執行緒任務(run):吃包子
- 對包子的狀態進行判斷
- false:沒有包子
- 吃貨呼叫wait方法進入等待狀態
- true:有包子
- 吃貨吃包子
- 吃貨吃完包子
- 修改包子的狀態為false沒有
- 吃貨喚醒包子鋪執行緒,生產包子
- false:沒有包子
6.7.5 測試類
- 測試類:
- 包含main方法,程式執行的入口,啟動程式
- 建立包子物件;
- 建立包子鋪執行緒,開啟,生產包子;
- 建立吃貨執行緒,開啟,吃包子;
7. 執行緒池、Lambda表示式
7.1 執行緒池
- 執行緒池:JDK1.5之後提供的
- java.util.concurrent.Executors:執行緒池的工廠類,用來生成執行緒池
- Executors類中的靜態方法:
- static ExecutorService newFixedThreadPool(int nThreads)
建立一個可重用固定執行緒數的執行緒池 - 引數:
- int nThreads:建立執行緒池中包含的執行緒數量
- 返回值:
- ExecutorService介面,返回的是ExecutorService介面的實現類物件,我們可以使用ExecutorService介面接收(面向介面程式設計)
- static ExecutorService newFixedThreadPool(int nThreads)
- java.util.concurrent.ExecutorService:執行緒池介面
- 用來從執行緒池中獲取執行緒,呼叫start方法,執行執行緒任務
submit(Runnable task) 提交一個 Runnable 任務用於執行 - 關閉/銷燬執行緒池的方法
void shutdown()
- 用來從執行緒池中獲取執行緒,呼叫start方法,執行執行緒任務
- 執行緒池的使用步驟:
- 使用執行緒池的工廠類Executors裡邊提供的靜態方法newFixedThreadPool生產一個指定執行緒數量的執行緒池
- 建立一個類,實現Runnable介面,重寫run方法,設定執行緒任務
- 呼叫ExecutorService中的方法submit,傳遞執行緒任務(實現類),開啟執行緒,執行run方法
- 呼叫ExecutorService中的方法shutdown銷燬執行緒池(不建議執行)
7.2 Lambda表示式
- Lambda表示式的標準格式:
- 由三部分組成:
- 一些引數
- 一個箭頭
- 一段程式碼
- 由三部分組成:
- 格式:
(引數列表) -> {一些重寫方法的程式碼};
- 解釋說明格式:
- ():介面中抽象方法的引數列表,沒有引數,就空著;有引數就寫出引數,多個引數使用逗號分隔
- ->:傳遞的意思,把引數傳遞給方法體{}
- {}:重寫介面的抽象方法的方法體
7.2.1 Lambda表示式條件
- Lambda表示式:是可推導,可以省略
- 凡是根據上下文推匯出來的內容,都可以省略書寫
- 可以省略的內容:
- (引數列表):括號中引數列表的資料型別,可以省略不寫
- (引數列表):括號中的引數如果只有一個,那麼型別和()都可以省略
- {一些程式碼}:如果{}中的程式碼只有一行,無論是否有返回值,都可以省略({},return,分號)
- 注意 : 要省略{},return,分號必須一起省略
8. File類、遞迴
8.1 File類
- java.io.File類
- 檔案和目錄路徑名的抽象表示形式。
- java把電腦中的檔案和資料夾(目錄)封裝為了一個File類,我們可以使用File類對檔案和資料夾進行操作
- 我們可以使用File類的方法
- 建立一個檔案/資料夾
- 刪除檔案/資料夾
- 獲取檔案/資料夾
- 判斷檔案/資料夾是否存在
- 對資料夾進行遍歷
- 獲取檔案的大小
- File類是一個與系統無關的類,任何的作業系統都可以使用這個類中的方法
- 重點:記住這三個單詞
- file : 檔案
- directory : 資料夾/目錄
- path : 路徑
8.1.1 父路徑和子路徑
- File(String parent, String child)
根據 parent 路徑名字串和 child 路徑名字串建立一個新 File 例項。- 引數:把路徑分成了兩部分
- String parent:父路徑
- String child:子路徑
- 好處:
- 父路徑和子路徑,可以單獨書寫,使用起來非常靈活;
- 父路徑和子路徑都可以變化
- 引數:把路徑分成了兩部分
8.1.2 File類獲取功能的方法
public String getAbsolutePath() :返回此File的絕對路徑名字串。
public String getPath() :將此File轉換為路徑名字串。
public String getName() :返回由此File表示的檔案或目錄的名稱。
public long length() :返回由此File表示的檔案的長度。
8.1.3 File類判斷功能的方法
public boolean exists() :此File表示的檔案或目錄是否實際存在。
public boolean isDirectory() :此File表示的是否為目錄。
public boolean isFile() :此File表示的是否為檔案。
8.1.4 File類建立刪除功能的方法
public boolean createNewFile() :當且僅當具有該名稱的檔案尚不存在時,建立一個新的空檔案。
public boolean