1. 程式人生 > >JavaSE高階【吐血整理彙總】

JavaSE高階【吐血整理彙總】

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,把文字解析為日期
  • 使用步驟:
    1. 建立SimpleDateFormat物件,構造方法中傳遞指定的模式
    2. 呼叫SimpleDateFormat物件中的方法parse,把符合構造方法中模式的字串,解析為Date日期
  • 注意:
    • public Date parse(String source) throws ParseException
    • parse方法聲明瞭一個異常叫ParseException
    • 如果字串和構造方法的模式不一樣,那麼程式就會丟擲此異常
    • 呼叫一個丟擲了異常的方法,就必須的處理這個異常,要麼throws繼續丟擲這個異常,要麼try catch自己處理
1.2.3 DateFormat類format方法
  • 使用DateFormat類中的方法format,把日期格式化為文字
  • 使用步驟:
    1. 建立SimpleDateFormat物件,構造方法中傳遞指定的模式
    2. 呼叫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; 秒

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]

1.5 StringBuilder類

  • java.lang.StringBuilder類:字串緩衝區,可以提高字串的效率
  • 構造方法:
    • StringBuilder()
      構造一個不帶任何字元的字串生成器,其初始容量為 16 個字元。
    • StringBuilder(String str)
      構造一個字串生成器,並初始化為指定的字串內容。
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)
    1. 基本型別的值+"" 最簡單的方法(工作中常用)
    2. 包裝類的靜態方法toString(引數),不是Object類的toString() 過載

      static String toString(int i) 返回一個表示指定整數的 String 物件。
    3. String類的靜態方法valueOf(引數)

      static String valueOf(int i) 返回 int 引數的字串表示形式。
  • 字串(String)->基本型別
    • 使用包裝類的靜態方法parseXXX(“字串”);
      • Integer類: static int parseInt(String s)
      • Double類: static double parseDouble(String s)

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() 返回迭代的下一個元素。

        取出集合中的下一個元素
    • Iterator迭代器,是一個介面,我們無法直接使用,需要使用Iterator介面的實現類物件,獲取實現類的方式比較特殊
    • Collection介面中有一個方法,叫iterator(),這個方法返回的就是迭代器的實現類物件
      Iterator iterator() 返回在此 collection 的元素上進行迭代的迭代器。
  • 迭代器的使用步驟(重點):
    1. 使用集合中的方法iterator()獲取迭代器的實現類物件,使用Iterator介面接收(多型)
    2. 使用Iterator介面中的方法hasNext判斷還有沒有下一個元素
    3. 使用Iterator介面中的方法next取出集合中的下一個元素

2.3 增強for

  • 增強for迴圈:底層使用的也是迭代器,使用for迴圈的格式,簡化了迭代器的書寫
    • 是JDK1.5之後出現的新特性
    • Collectionextends Iterable : 所有的單列集合都可以使用增強for
    • public interface Iterable實現這個介面允許物件成為 “foreach” 語句的目標。
  • 增強for迴圈:用來遍歷集合和陣列
    • 格式:
      for(集合/陣列的資料型別 變數名: 集合名/陣列名){
          sout(變數名);
      }
      

2.4 泛型

  • 建立集合物件,使用泛型
    • 好處:
      1. 避免了型別轉換的麻煩,儲存的是什麼型別,取出的就是什麼型別
      2. 把執行期異常(程式碼執行之後會丟擲的異常),提升到了編譯期(寫程式碼的時候會報錯)
    • 弊端:
      • 泛型是什麼型別,只能儲存什麼型別的資料
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介面的特點:
      1. 有序的集合,儲存元素和取出元素的順序是一致的(儲存123 取出123)
      2. 有索引,包含了一些帶索引的方法
      3. 允許儲存重複的元素
    • 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:字串索引越界異常
3.1.1 LinkedList集合
  • java.util.LinkedList集合 implements List介面
    • LinkedList集合的特點:

      1. 底層是一個連結串列結構:查詢慢,增刪快
      2. 裡邊包含了大量操作首尾元素的方法

      注意:使用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介面的特點:
      1. 不允許儲存重複的元素
      2. 沒有索引,沒有帶索引的方法,也不能使用普通的for迴圈遍歷
  • java.util.HashSet集合 implements Set介面
    • HashSet特點:
      1. 不允許儲存重複的元素
      2. 沒有索引,沒有帶索引的方法,也不能使用普通的for迴圈遍歷
      3. 是一個無序的集合,儲存元素和取出元素的順序有可能不一致
      4. 底層是一個雜湊表結構(查詢的速度非常的快)
3.2.1 LinkedHashSet集合
  • java.util.LinkedHashSet集合 extends HashSet集合
    • 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定義排序的規則
    • 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集合的特點:
      1. Map集合是一個雙列集合,一個元素包含兩個值(一個key,一個value)
      2. Map集合中的元素,key和value的資料型別可以相同,也可以不同
      3. Map集合中的元素,key是不允許重複的,value是可以重複的
      4. Map集合中的元素,key和value是一一對應
  • java.util.HashMap<k,v>集合 implements Map<k,v>介面
    • HashMap集合的特點:
      1. HashMap集合底層是雜湊表:查詢的速度特別的快
        • JDK1.8之前:陣列+單向連結串列
        • JDK1.8之後:陣列+單向連結串列|紅黑樹(連結串列的長度超過8):提高查詢的速度
      2. hashMap集合是一個無序的集合,儲存元素和取出元素的順序有可能不一致
  • java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合
    • LinkedHashMap的特點:
      1. LinkedHashMap集合底層是雜湊表+連結串列(保證迭代的順序)
      2. LinkedHashMap集合是一個有序的集合,儲存元素和取出元素的順序是一致的
4.1.1 keySet()
  • Map集合的第一種遍歷方式:通過鍵找值的方式
    • Map集合中的方法:

      Set keySet() 返回此對映中包含的鍵的 Set 檢視。
    • 實現步驟:
      1. 使用Map集合中的方法keySet(),把Map集合所有的key取出來,儲存到一個Set集合中
      2. 遍歷set集合,獲取Map集合中的每一個key
      3. 通過Map集合中的方法get(key),通過key找到value
4.1.2 entrySet()
  • Map集合遍歷的第二種方式:使用Entry物件遍歷
    • Map集合中的方法:

      Set<Map.Entry<K,V>> entrySet() 返回此對映中包含的對映關係的 Set 檢視。
    • 實現步驟:
      1. 使用Map集合中的方法entrySet(),把Map集合中多個Entry物件取出來,儲存到一個Set集合中
      2. 遍歷Set集合,獲取每一個Entry物件
      3. 使用Entry物件中的方法getKey()和getValue()獲取鍵與值
4.1.3 自定義型別鍵值
  • HashMap儲存自定義型別鍵值
    • Map集合保證key是唯一的:
      • 作為key的元素,必須重寫hashCode方法和equals方法,以保證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)
    • 使用前提:
      • 當集合中儲存的元素的個數已經確定了,不在改變時使用
  • 注意:
    1. of方法只適用於List介面,Set介面,Map介面,不適用於接介面的實現類
    2. of方法的返回值是一個不能改變的集合,集合不能再使用add,put方法新增元素,會丟擲異常
    3. 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:錯誤
      • 錯誤就相當於程式得了一個無法治癒的毛病(非典,艾滋).必須修改原始碼,程式才能繼續執行

5.2 throws關鍵字

  • throws關鍵字:異常處理的第一種方式,交給別人處理
  • 作用:
    • 當方法內部丟擲異常物件的時候,那麼我們就必須處理這個異常物件
    • 可以使用throws關鍵字處理異常物件,會把異常物件宣告丟擲給方法的呼叫者處理(自己不處理,給別人處理),最終交給JVM處理–>中斷處理
  • 使用格式:在方法宣告時使用
    修飾符 返回值型別 方法名(引數列表) throws AAAExcepiton,BBBExcepiton...{
        throw new AAAExcepiton("產生原因");
        throw new BBBExcepiton("產生原因");
        ...
    }
    
  • 注意:
    1. throws關鍵字必須寫在方法宣告處
    2. throws關鍵字後邊宣告的異常必須是Exception或者是Exception的子類
    3. 方法內部如果丟擲了多個異常物件,那麼throws後邊必須也宣告多個異常
      如果丟擲的多個異常物件有子父類關係,那麼直接宣告父類異常即可
    4. 呼叫了一個宣告丟擲異常的方法,我們就必須的處理宣告的異常

      要麼繼續使用throws宣告丟擲,交給方法的呼叫者處理,最終交給JVM

      要麼try…catch自己處理異常

5.3 try…catch

  • try…catch:異常處理的第二種方式,自己處理異常
  • 格式:
    try{
        可能產生異常的程式碼
    }catch(定義一個異常的變數,用來接收try中丟擲的異常物件){
        異常的處理邏輯,異常異常物件之後,怎麼處理異常物件
        一般在工作中,會把異常的資訊記錄到一個日誌中
    }
    ...
    catch(異常類名 變數名){
    
    }
    
  • 注意:
    1. try中可能會丟擲多個異常物件,那麼就可以使用多個catch來處理這些異常物件
    2. 如果try中產生了異常,那麼就會執行catch中的異常處理邏輯,執行完畢catch中的處理邏輯,繼續執行try…catch之後的程式碼
    3. 如果try中沒有產生異常,那麼就不會執行catch中異常的處理邏輯,執行完try中的程式碼,繼續執行try…catch之後的程式碼

5.4 finally程式碼塊

  • 格式:
    try{
        可能產生異常的程式碼
    }catch(定義一個異常的變數,用來接收try中丟擲的異常物件){
        異常的處理邏輯,異常異常物件之後,怎麼處理異常物件
        一般在工作中,會把異常的資訊記錄到一個日誌中
    }
    ...
    catch(異常類名 變數名){
    
    }finally{
        無論是否出現異常都會執行
    }
    
  • 注意:
    1. finally不能單獨使用,必須和try一起使用
    2. finally一般用於資源釋放(資源回收),無論程式是否出現異常,最後都要資源釋放(IO)

5.5 子父類的異常

  • 如果父類丟擲了多個異常,子類重寫父類方法時,丟擲和父類相同的異常或者是父類異常的子類或者不丟擲異常。
  • 父類方法沒有丟擲異常,子類重寫父類該方法時也不可丟擲異常。此時子類產生該異常,只能捕獲處理,不能宣告丟擲
  • 注意 : 父類異常時什麼樣,子類異常就什麼樣

5.6 自定義異常類

  • java提供的異常類,不夠我們使用,需要自己定義一些異常類
  • 格式:
    public class XXXExcepiton extends Exception | RuntimeException{
        新增一個空引數的構造方法
        新增一個帶異常資訊的構造方法
    }
    
  • 注意:
    1. 自定義異常類一般都是以Exception結尾,說明該類是一個異常類
    2. 自定義異常類,必須的繼承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類
  • 實現步驟:
    1. 建立一個Thread類的子類
    2. 在Thread類的子類中重寫Thread類中的run方法,設定執行緒任務(開啟執行緒要做什麼?)
    3. 建立Thread類的子類物件
    4. 呼叫Thread類中的方法start方法,開啟新的執行緒,執行run方法

      void start() 使該執行緒開始執行;Java 虛擬機器呼叫該執行緒的 run 方法。

      結果是兩個執行緒併發地執行;當前執行緒(main執行緒)和另一個執行緒(建立的新執行緒,執行其 run 方法)。

      多次啟動一個執行緒是非法的。特別是當執行緒已經結束執行後,不能再重新啟動。
  • java程式屬於搶佔式排程,那個執行緒的優先順序高,那個執行緒優先執行;同一個優先順序,隨機選擇一個執行
6.1.1 執行緒的名稱
  • 主執行緒: main
  • 新執行緒: Thread-0,Thread-1,Thread-2
6.1.2 獲取執行緒的名稱
  1. 使用Thread類中的方法getName()
    • String getName() 返回該執行緒的名稱。
  2. 可以先獲取到當前正在執行的執行緒,使用執行緒中的方法getName()獲取執行緒的名稱
    • static Thread currentThread() 返回對當前正在執行的執行緒物件的引用。
6.1.3 設定執行緒的名稱
  1. 使用Thread類中的方法setName(名字)
    • void setName(String name) 改變執行緒名稱,使之與引數 name 相同。
  2. 建立一個帶引數的構造方法,引數傳遞執行緒的名稱;呼叫父類的帶參構造方法,把執行緒名稱傳遞給父類,讓父類(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 物件。
  • 實現步驟:
    1. 建立一個Runnable介面的實現類
    2. 在實現類中重寫Runnable介面的run方法,設定執行緒任務
    3. 建立一個Runnable介面的實現類物件
    4. 建立Thread類物件,構造方法中傳遞Runnable介面的實現類物件
    5. 呼叫Thread類中的start方法,開啟新的執行緒執行run方法
  • 實現Runnable介面建立多執行緒程式的好處:
    1. 避免了單繼承的侷限性
      • 一個類只能繼承一個類(一個人只能有一個親爹),類繼承了Thread類就不能繼承其他的類
      • 實現了Runnable介面,還可以繼承其他的類,實現其他的介面
    2. 增強了程式的擴充套件性,降低了程式的耦合性(解耦)
      • 實現Runnable介面的方式,把設定執行緒任務和開啟新執行緒進行了分離(解耦)
      • 實現類中,重寫了run方法:用來設定執行緒任務
      • 建立Thread類物件,呼叫start方法:用來開啟新執行緒

6.3 匿名內部類方式建立執行緒

  • 匿名:沒有名字
  • 內部類:寫在其他類內部的類
  • 匿名內部類作用:簡化程式碼
    • 把子類繼承父類,重寫父類的方法,建立子類物件合一步完成
    • 把實現類實現類介面,重寫介面中的方法,建立實現類物件合成一步完成
  • 匿名內部類的最終產物:子類/實現類物件,而這個類沒有名字
    • 格式:
      new 父類/介面(){
          重複父類/介面中的方法
      };
      

6.4 執行緒安全問題-同步程式碼塊

  • 解決執行緒安全問題的一種方案:使用同步程式碼塊
  • 格式:
    synchronized(鎖物件){
        可能會出現執行緒安全問題的程式碼(訪問了共享資料的程式碼)
    }
    
  • 注意:
    1. 通過程式碼塊中的鎖物件,可以使用任意的物件
    2. 但是必須保證多個執行緒使用的鎖物件是同一個
    3. 鎖物件作用:
      把同步程式碼塊鎖住,只讓一個執行緒在同步程式碼塊中執行

6.5 執行緒安全問題-同步方法

  • 解決執行緒安全問題的二種方案:使用同步方法
  • 使用步驟:
    1. 把訪問了共享資料的程式碼抽取出來,放到一個方法中
    2. 在方法上新增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介面
  • 使用步驟:
    1. 在成員位置建立一個ReentrantLock物件
    2. 在可能會出現安全問題的程式碼前呼叫Lock介面中的方法lock獲取鎖
    3. 在可能會出現安全問題的程式碼後呼叫Lock介面中的方法unlock釋放鎖

6.7 執行緒間通訊

  • 等待喚醒案例:執行緒之間的通訊
    • 建立一個顧客執行緒(消費者):告知老闆要的包子的種類和數量,呼叫wait方法,放棄cpu的執行,進入到WAITING狀態(無限等待)
    • 建立一個老闆執行緒(生產者):花了5秒做包子,做好包子之後,呼叫notify方法,喚醒顧客吃包子
  • 注意:
    • 顧客和老闆執行緒必須使用同步程式碼塊包裹起來,保證等待和喚醒只能有一個在執行
    • 同步使用的鎖物件必須保證唯一
    • 只有鎖物件才能呼叫wait和notify方法
  • Obejct類中的方法
    • void wait()

      在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法前,導致當前執行緒等待。
    • void notify()

      喚醒在此物件監視器上等待的單個執行緒。

      會繼續執行wait方法之後的程式碼
6.7.1 計時等待的兩種方式
  • 進入到TimeWaiting(計時等待)有兩種方式
    1. 使用sleep(long m)方法,在毫秒值結束之後,執行緒睡醒進入到Runnable/Blocked狀態
    2. 使用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有
        • 喚醒吃貨執行緒,讓吃貨執行緒吃包子
  • 注意:
    • 包子鋪執行緒和包子執行緒關係–>通訊(互斥)
    • 必須同時同步技術保證兩個執行緒只能有一個在執行
    • 鎖物件必須保證唯一,可以使用包子物件作為鎖物件
    • 包子鋪類和吃貨的類就需要把包子物件作為引數傳遞進來
      1. 需要在成員位置建立一個包子變數
      2. 使用帶引數構造方法,為這個包子變數賦值
6.7.4 消費者類
  • 消費者(吃貨)類:是一個執行緒類,可以繼承Thread
    • 設定執行緒任務(run):吃包子
    • 對包子的狀態進行判斷
      • false:沒有包子
        • 吃貨呼叫wait方法進入等待狀態
      • true:有包子
        • 吃貨吃包子
        • 吃貨吃完包子
        • 修改包子的狀態為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介面接收(面向介面程式設計)
  • java.util.concurrent.ExecutorService:執行緒池介面
    • 用來從執行緒池中獲取執行緒,呼叫start方法,執行執行緒任務

      submit(Runnable task) 提交一個 Runnable 任務用於執行
    • 關閉/銷燬執行緒池的方法

      void shutdown()
  • 執行緒池的使用步驟:
    1. 使用執行緒池的工廠類Executors裡邊提供的靜態方法newFixedThreadPool生產一個指定執行緒數量的執行緒池
    2. 建立一個類,實現Runnable介面,重寫run方法,設定執行緒任務
    3. 呼叫ExecutorService中的方法submit,傳遞執行緒任務(實現類),開啟執行緒,執行run方法
    4. 呼叫ExecutorService中的方法shutdown銷燬執行緒池(不建議執行)

7.2 Lambda表示式

  • Lambda表示式的標準格式:
    • 由三部分組成:
      • 一些引數
      • 一個箭頭
      • 一段程式碼
  • 格式:
    (引數列表) -> {一些重寫方法的程式碼};
    
  • 解釋說明格式:
    • ():介面中抽象方法的引數列表,沒有引數,就空著;有引數就寫出引數,多個引數使用逗號分隔
    • ->:傳遞的意思,把引數傳遞給方法體{}
    • {}:重寫介面的抽象方法的方法體
7.2.1 Lambda表示式條件
  • Lambda表示式:是可推導,可以省略
  • 凡是根據上下文推匯出來的內容,都可以省略書寫
  • 可以省略的內容:
    1. (引數列表):括號中引數列表的資料型別,可以省略不寫
    2. (引數列表):括號中的引數如果只有一個,那麼型別和()都可以省略
    3. {一些程式碼}:如果{}中的程式碼只有一行,無論是否有返回值,都可以省略({},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