尚硅谷Java——宋紅康筆記【day11-day18】


day11

Eclipse中的快捷鍵:

 * 1.補全代碼的聲明:alt + /
 * 2.快速修復: ctrl + 1  
 * 3.批量導包:ctrl + shift + o
 * 4.使用單行注釋:ctrl + /
 * 5.使用多行注釋: ctrl + shift + /   
 * 6.取消多行注釋:ctrl + shift + \
 * 7.復制指定行的代碼:ctrl + alt + down 或 ctrl + alt + up
 * 8.刪除指定行的代碼:ctrl + d
 * 9.上下移動代碼:alt + up  或 alt + down
 * 10.切換到下一行代碼空位:shift + enter
 * 11.切換到上一行代碼空位:ctrl + shift + enter
 * 12.如何查看源碼:ctrl + 選中指定的結構   或  ctrl + shift + t
 * 13.退回到前一個編輯的頁面:alt + left 
 * 14.進入到下一個編輯的頁面(針對於上面那條來說的):alt + right
 * 15.光標選中指定的類,查看繼承樹結構:ctrl + t
 * 16.復制代碼: ctrl + c
 * 17.撤銷: ctrl + z
 * 18.反撤銷: ctrl + y
 * 19.剪切:ctrl + x 
 * 20.粘貼:ctrl + v
 * 21.保存: ctrl + s
 * 22.全選:ctrl + a
 * 23.格式化代碼: ctrl + shift + f
 * 24.選中數行,整體往后移動:tab
 * 25.選中數行,整體往前移動:shift + tab
 * 26.在當前類中,顯示類結構,並支持搜索指定的方法、屬性等:ctrl + o
 * 27.批量修改指定的變量名、方法名、類名等:alt + shift + r
 * 28.選中的結構的大小寫的切換:變成大寫: ctrl + shift + x
 * 29.選中的結構的大小寫的切換:變成小寫:ctrl + shift + y
 * 30.調出生成getter/setter/構造器等結構: alt + shift + s
 * 31.顯示當前選擇資源(工程 or 文件)的屬性:alt + enter
 * 32.快速查找:參照選中的Word快速定位到下一個 :ctrl + k
 * 33.關閉當前窗口:ctrl + w
 * 34.關閉所有的窗口:ctrl + shift + w
 * 35.查看指定的結構使用過的地方:ctrl + alt + g
 * 36.查找與替換:ctrl + f
 * 37.最大化當前的View:ctrl + m
 * 38.直接定位到當前行的首位:home
 * 39.直接定位到當前行的末位:end

面向對象的特征之二:繼承性 why?

一、繼承性的好處:

① 減少了代碼的冗余,提高了代碼的復用性

② 便於功能的擴展

③ 為之后多態性的使用,提供了前提

二、繼承性的格式: class A extends B{}

A:子類、派生類、subclass

B:父類、超類、基類、superclass

2.1體現:一旦子類A繼承父類B以后,子類A中就獲取了父類B中聲明的所有的屬性和方法。特別的,父類中聲明為private的屬性或方法,子類繼承父類以后,仍然認為獲取了父類中私有的結構。只有因為封裝性的影響,使得子類不能直接調用父類的結構而已。

2.2 子類繼承父類以后,還可以聲明自己特有的屬性或方法:實現功能的拓展。子類和父類的關系,不同於子集和集合的關系。

extends:延展、擴展

三、Java中關於繼承性的規定:

1.一個類可以被多個子類繼承。

2.Java中類的單繼承性:一個類只能有一個父類

3.子父類是相對的概念。

4.子類直接繼承的父類,稱為:直接父類。間接繼承的父類稱為:間接父類

5.子類繼承父類以后,就獲取了直接父類以及所有間接父類中聲明的屬性和方法

四、 1.如果我們沒有顯式的聲明一個類的父類的話,則此類繼承於java.lang.Object類

2.所有的java類(除java.lang.Object類之外)都直接或間接的繼承於java.lang.Object類

3.意味着,所有的java類具有java.lang.Object類聲明的功能。

day12

方法的重寫(override / overwrite)

1.重寫:子類繼承父類以后,可以對父類中同名同參數的方法,進行覆蓋操作

2.應用:重寫以后,當創建子類對象以后,通過子類對象調用子父類中的同名同參數的方法時,實際執行的是子類重寫父類的方法。

  1. 重寫的規定:

    方法的聲明: 權限修飾符 返回值類型 方法名(形參列表) throws 異常的類型{}

約定俗稱:子類中的叫重寫的方法,父類中的叫被重寫的方法

① 子類重寫的方法的方法名和形參列表與父類被重寫的方法的方法名和形參列表相同

② 子類重寫的方法的權限修飾符不小於父類被重寫的方法的權限修飾符

特殊情況:子類不能重寫父類中聲明為private權限的方法

③ 返回值類型:

父類被重寫的方法的返回值類型是void,則子類重寫的方法的返回值類型只能是void

父類被重寫的方法的返回值類型是A類型,則子類重寫的方法的返回值類型可以是A類或A類的子類

父類被重寫的方法的返回值類型是基本數據類型(比如:double),則子類重寫的方法的返回值類型必須是相同的基本數據類型(必須也是double)

④ 子類重寫的方法拋出的異常類型不大於父類被重寫的方法拋出的異常類型(具體放到異常處理時候講)

子類和父類中的同名同參數的方法要么都聲明為非static的(考慮重寫),要么都聲明為static的(不是重寫)。

  • 面試題:區分方法的重載與重寫

super關鍵字的使用

1.super理解為:父類的

2.super可以用來調用:屬性、方法、構造器

3.super的使用:調用屬性和方法

  • 3.1 我們可以在子類的方法或構造器中。通過使用"super.屬性"或"super.方法"的方式,顯式的調用父類中聲明的屬性或方法。但是,通常情況下,我們習慣省略"super."
  • 3.2 特殊情況:當子類和父類中定義了同名的屬性時,我們要想在子類中調用父類中聲明的屬性,則必須顯式的使用"super.屬性"的方式,表明調用的是父類中聲明的屬性。
  • 3.3 特殊情況:當子類重寫了父類中的方法以后,我們想在子類的方法中調用父類中被重寫的方法時,則必須顯式的使用"super.方法"的方式,表明調用的是父類中被重寫的方法。

4.super調用構造器

  • 4.1 我們可以在子類的構造器中顯式的使用"super(形參列表)"的方式,調用父類中聲明的指定的構造器
  • 4.2 "super(形參列表)"的使用,必須聲明在子類構造器的首行!
  • 4.3 我們在類的構造器中,針對於"this(形參列表)"或"super(形參列表)"只能二選一,不能同時出現
  • 4.4 在構造器的首行,沒有顯式的聲明"this(形參列表)"或"super(形參列表)",則默認調用的是父類中空參的構造器:super()
  • 4.5 在類的多個構造器中,至少有一個類的構造器中使用了"super(形參列表)",調用父類中的構造器

子類對象實例化的全過程

1.從結果上來看:(繼承性)

  • 子類繼承父類以后,就獲取了父類中聲明的屬性或方法。
  • 創建子類的對象,在堆空間中,就會加載所有父類中聲明的屬性。

2.從過程上來看:

  • 當我們通過子類的構造器創建子類對象時,我們一定會直接或間接的調用其父類的構造器,進而調用父類的父類的構造器,...
  • 直到調用了java.lang.Object類中空參的構造器為止。正因為加載過所有的父類的結構,所以才可以看到內存中有
  • 父類中的結構,子類對象才可以考慮進行調用。

明確:雖然創建子類對象時,調用了父類的構造器,但是自始至終就創建過一個對象,即為new的子類對象

面向對象特征之三:多態性

1.理解多態性:可以理解為一個事物的多種形態。

2.何為多態性:

對象的多態性:父類的引用指向子類的對象(或子類的對象賦給父類的引用)

  1. 多態的使用:虛擬方法調用

有了對象的多態性以后,我們在編譯期,只能調用父類中聲明的方法,但在運行期,我們實際執行的是子類重寫父類的方法。

總結:編譯,看左邊;運行,看右邊。

4.多態性的使用前提: ① 類的繼承關系 ② 方法的重寫

5.對象的多態性,只適用於方法,不適用於屬性(編譯和運行都看左邊)

day13

instanceof的使用和向下轉型

x instanceof A:檢驗x是否為類A的對象,返回值為boolean型

使用情境:為了避免在向下轉型時出現ClassCastException的異常,我們在向下轉型之前,先進行instanceof的判斷,一旦返回true,就進行向下轉型。如果返回false,不進行向下轉型。

如果 a instanceof A返回true,則 a instanceof B也返回true.其中,類B是類A的父類。

  • 多態的使用:當調用子父類同名同參數的方法時,實際執行的是子類重寫父類的方法 ---虛擬方法調用
  • 有了對象的多態性以后,內存中實際上是加載了子類特有的屬性和方法的,但是由於變量聲明為父類類型,導致編譯時,只能調用父類中聲明的屬性和方法。子類特有的屬性和方法不能調用。

如何才能調用子類特有的屬性和方法?—— 向下轉型:使用強制類型轉換符。(Man m1 = (Man)p2;

java.lang.Object類

1.Object類是所有Java類的根父類

2.如果在類的聲明中未使用extends關鍵字指明其父類,則默認父類為java.lang.Object類

3.Object類中的功能(屬性、方法)就具有通用性。

  • 屬性:無
  • 方法:equals() / toString() / getClass() /hashCode() / clone() / finalize() / wait() 、 notify()、notifyAll()

4.Object類只聲明了一個空參的構造器

equals()

一、回顧 == 的使用:

== :運算符

1.可以使用在基本數據類型變量和引用數據類型變量中

2.如果比較的是基本數據類型變量:比較兩個變量保存的數據是否相等。(不一定類型要相同)

如果比較的是引用數據類型變量:比較兩個對象的地址值是否相同.即兩個引用是否指向同一個對象實體

補充: == 符號使用時,必須保證符號左右兩邊的變量類型一致。

二、equals()方法的使用:

1.是一個方法,而非運算符

2.只能適用於引用數據類型

3.Object類中equals()的定義:

public boolean equals(Object obj) {
    return (this == obj);
}

說明:Object類中定義的equals()和==的作用是相同的:比較兩個對象的地址值是否相同.即兩個引用是否指向同一個對象實體

4.像String、Date、File、包裝類等都重寫了Object類中的equals()方法。重寫以后,比較的不是兩個引用的地址是否相同,而是比較兩個對象的"實體內容"是否相同。

5.通常情況下,我們自定義的類如果使用equals()的話,也通常是比較兩個對象的"實體內容"是否相同。那么,我們就需要對Object類中的equals()進行重寫.

重寫的原則:比較兩個對象的實體內容是否相同

bject類中toString()的使用:

1.當我們輸出一個對象的引用時,實際上就是調用當前對象的toString()

2.Object類中toString()的定義:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
 }

3.像String、Date、File、包裝類等都重寫了Object類中的toString()方法。使得在調用對象的toString()時,返回"實體內容"信息

4.自定義類也可以重寫toString()方法,當調用此方法時,返回對象的"實體內容"

Java中的JUnit單元測試

(eclipse)步驟:

1.選中當前工程 - 右鍵選擇:build path - add libraries - JUnit 4 - 下一步

2.創建Java類,進行單元測試。此時的Java類要求:① 此類是public的 ②此類提供公共的無參的構造器

3.此類中聲明單元測試方法。此時的單元測試方法:方法的權限是public,沒有返回值,沒有形參

4.此單元測試方法上需要聲明注解:@Test,並在單元測試類中導入:import org.junit.Test;

5.聲明好單元測試方法以后,就可以在方法體內測試相關的代碼。

6.寫完代碼以后,左鍵雙擊單元測試方法名,右鍵:run as - JUnit Test

說明:

  • 1.如果執行結果沒有任何異常:綠條
  • 2.如果執行結果出現異常:紅條

包裝類

1.java提供了8種基本數據類型對應的包裝類,使得基本數據類型的變量具有類的特征

2.掌握的:基本數據類型、包裝類、String三者之間的相互轉換

基本數據類型 --->包裝類:調用包裝類的構造器

    public void test1(){
    int num1 = 10;

// System.out.println(num1.toString());
Integer in1 = new Integer(num1);
System.out.println(in1.toString());

    Integer in2 = new Integer("123");
    System.out.println(in2.toString());

    //報異常

// Integer in3 = new Integer("123abc");
// System.out.println(in3.toString());

    Float f1 = new Float(12.3f);
    Float f2 = new Float("12.3");
    System.out.println(f1);
    System.out.println(f2);

    Boolean b1 = new Boolean(true);
    Boolean b2 = new Boolean("TrUe");
    System.out.println(b2);
    Boolean b3 = new Boolean("true123");
    System.out.println(b3);//false

    //特別注意此處,分別是boolean和Boolean,都沒定義的情況下一個返回false一個返回null
    Order order = new Order();
    System.out.println(order.isMale);//false
    System.out.println(order.isFemale);//null
}

}

class Order{

boolean isMale;
Boolean isFemale;

}

基本數據類型:調用包裝類Xxx的xxxValue()

public void test2(){
    Integer in1 = new Integer(12);
int i1 = in1.intValue();
System.out.println(i1 + 1);


Float f1 = new Float(12.3);
float f2 = f1.floatValue();
System.out.println(f2 + 1);

}

JDK 5.0 新特性:自動裝箱 與自動拆箱

public void test3(){
    //int num1 = 10;
    //基本數據類型-->包裝類的對象
    //method(num1);
//自動裝箱:基本數據類型 --->包裝類
int num2 = 10;
Integer in1 = num2;//自動裝箱

boolean b1 = true;
Boolean b2 = b1;//自動裝箱

//自動拆箱:包裝類--->基本數據類型
System.out.println(in1.toString());

int num3 = in1;//自動拆箱

}

public void method(Object obj){
System.out.println(obj);
}

基本數據類型、包裝類--->String類型:調用String重載的valueOf(Xxx xxx)

public void test4(){
int num1 = 10;
//方式1:連接運算
String str1 = num1 + "";
//方式2:調用String的valueOf(Xxx xxx)
float f1 = 12.3f;
String str2 = String.valueOf(f1);//"12.3"

Double d1 = new Double(12.4);
String str3 = String.valueOf(d1);
System.out.println(str2);
System.out.println(str3);//"12.4"

}

String類型 --->基本數據類型、包裝類:調用包裝類的parseXxx(String s)

public void test5(){
    String str1 = "123";
    //錯誤的情況:沒有相關性
    //int num1 = (int)str1;
    //Integer in1 = (Integer)str1;
    //可能會報NumberFormatException
    int num2 = Integer.parseInt(str1);
    System.out.println(num2 + 1);
String str2 = "true1";
boolean b1 = Boolean.parseBoolean(str2);
System.out.println(b1);

}

總結

包裝類面試題

題1

答案:第一題是1.0;第二題是1。 解析:true ? new Integer(1) : new Double(2.0);編譯的時候,這段代碼得保證true后面的數據類型一致,所以提升為Double

題2

public void test3() {
    Integer i = new Integer(1);
    Integer j = new Integer(1);
    System.out.println(i == j);//false
//Integer內部定義了IntegerCache結構,IntegerCache中定義了Integer[],
//保存了從-128~127范圍的整數。如果我們使用自動裝箱的方式,給Integer賦值的范圍在
//-128~127范圍內時,可以直接使用數組中的元素,不用再去new了。目的:提高效率

Integer m = 1;
Integer n = 1;
System.out.println(m == n);//true

Integer x = 128;//相當於new了一個Integer對象
Integer y = 128;//相當於new了一個Integer對象
System.out.println(x == y);//false

}

day14

static關鍵字的使用

1.static:靜態的

2.static可以用來修飾:屬性、方法、代碼塊、內部類

3.使用static修飾屬性:靜態變量(或類變量)

3.1 屬性,按是否使用static修飾,又分為:靜態屬性 vs 非靜態屬性(實例變量)

實例變量:我們創建了類的多個對象,每個對象都獨立的擁有一套類中的非靜態屬性。當修改其中一個對象中的非靜態屬性時,不會導致其他對象中同樣的屬性值的修改。

靜態變量:我們創建了類的多個對象,多個對象共享同一個靜態變量。當通過某一個對象修改靜態變量時,會導致其他對象調用此靜態變量時,是修改過了的。

3.2 static修飾屬性的其他說明:

① 靜態變量隨着類的加載而加載。可以通過"類.靜態變量"的方式進行調用

② 靜態變量的加載要早於對象的創建。

③ 由於類只會加載一次,則靜態變量在內存中也只會存在一份:存在方法區的靜態域中。

④ 類:類變量(√) 實例變量(×)

對象:類變量(√) 實例變量(√)

3.3 靜態屬性舉例:System.out; Math.PI;

4.使用static修飾方法:靜態方法

① 隨着類的加載而加載,可以通過"類.靜態方法"的方式進行調用

②類:靜態變量(√) 非靜態變量(×)

對象:靜態變量(√) 非靜態變量(√)

③ 靜態方法中,只能調用靜態的方法或屬性;非靜態方法中,既可以調用非靜態的方法或屬性,也可以調用靜態的方法或屬性

  1. static注意點:

5.1 在靜態的方法內,不能使用this關鍵字、super關鍵字

5.2 關於靜態屬性和靜態方法的使用,大家都從生命周期的角度去理解。

6.開發中,如何確定一個屬性是否要聲明為static的?

屬性是可以被多個對象所共享的,不會隨着對象的不同而不同的。

類中的常量也常常聲明為static

開發中,如何確定一個方法是否要聲明為static的?

操作靜態屬性的方法,通常設置為static的

工具類中的方法,習慣上聲明為stati c的。 比如:Math、Arrays、Collections

單例設計模式:

  1. 所謂類的單例設計模式,就是采取一定的方法保證在整個的軟件系統中,對某個類只能存在一個對象實例。

  2. 如何實現?

餓漢式 vs 懶漢式

  1. 區分餓漢式 和 懶漢式

餓漢式:

  • 壞處:對象加載時間過長。
  • 好處:餓漢式是線程安全的

懶漢式:

  • 好處:延遲對象的創建。
  • 目前的寫法壞處:線程不安全。--->到多線程內容時,再修改

main()方法的使用說明:

  • 1. main()方法作為程序的入口
  • 2. main()方法也是一個普通的靜態方法
  • 3. main()方法可以作為我們與控制台交互的方式。(之前:使用Scanner)

類的成員之四:代碼塊(或初始化塊)

1.代碼塊的作用:用來初始化類、對象

2.代碼塊如果有修飾的話,只能使用static.

3.分類:靜態代碼塊 vs 非靜態代碼塊

4.靜態代碼塊

內部可以有輸出語句

隨着類的加載而執行,而且只執行一次

作用:初始化類的信息

如果一個類中定義了多個靜態代碼塊,則按照聲明的先后順序執行

靜態代碼塊的執行要優先於非靜態代碼塊的執行

靜態代碼塊內只能調用靜態的屬性、靜態的方法,不能調用非靜態的結構

5.非靜態代碼塊

內部可以有輸出語句

隨着對象的創建而執行

每創建一個對象,就執行一次非靜態代碼塊

作用:可以在創建對象時,對對象的屬性等進行初始化

如果一個類中定義了多個非靜態代碼塊,則按照聲明的先后順序執行

非靜態代碼塊內可以調用靜態的屬性、靜態的方法,或非靜態的屬性、非靜態的方法

對屬性可以賦值的位置:

  • ①默認初始化
  • ②顯式初始化/⑤在代碼塊中賦值
  • ③構造器中初始化
  • ④有了對象以后,可以通過"對象.屬性"或"對象.方法"的方式,進行賦值

執行的先后順序:① - ② / ⑤ - ③ - ④

final關鍵字

final:最終的

1.final可以用來修飾的結構:類、方法、變量

2.final 用來修飾一個類:此類不能被其他類所繼承。比如:String類、System類、StringBuffer類

3.final 用來修飾方法:表明此方法不可以被重寫。比如:Object類中getClass();

4.final 用來修飾變量:此時的"變量"就稱為是一個常量

4.1 final修飾屬性:可以考慮賦值的位置有:顯式初始化、代碼塊中初始化、構造器中初始化

4.2 final修飾局部變量:尤其是使用final修飾形參時,表明此形參是一個常量。當我們調用此方法時,給常量形參賦一個實參。一旦賦值以后,就只能在方法體內使用此形參,但不能進行重新賦值。

public void show(final int num){
    //num = 20;//編譯不通過
    System.out.println(num);
}

//不可以在方法內賦值,只有在調用時賦值,如test.show(10);

static final 用來修飾屬性:全局常量

面試題:排錯

public class Something{
    public int addOne(final int x){
        return ++x;//  錯誤的,因為改變了x;
        //return x + 1;//正確的。未改變x;
    }
}

day15

abstract關鍵字的使用

1.abstract:抽象的

2.abstract可以用來修飾的結構:類、方法

3.abstract修飾類:抽象類

此類不能實例化

抽象類中一定有構造器,便於子類實例化時調用(涉及:子類對象實例化的全過程)

開發中,都會提供抽象類的子類,讓子類對象實例化,完成相關的操作

4.abstract修飾方法:抽象方法

抽象方法只有方法的聲明,沒有方法體

包含抽象方法的類,一定是一個抽象類。反之,抽象類中可以沒有抽象方法的。

若子類重寫了父類中的所有的抽象方法后,此子類方可實例化;若子類沒有重寫父類中的所有的抽象方法,則此子類也是一個抽象類,需要使用abstract修飾

abstract使用上的注意點:

1.abstract不能用來修飾:屬性、構造器等結構

2.abstract不能用來修飾私有方法、靜態方法、final的方法、final的類

接口的使用

1.接口使用interface來定義

2.Java中,接口和類是並列的兩個結構

3.如何定義接口:定義接口中的成員

3.1 JDK7及以前:只能定義全局常量和抽象方法

全局常量:public static final的.但是書寫時,可以省略不寫

抽象方法:public abstract的

3.2 JDK8:除了定義全局常量和抽象方法之外,還可以定義靜態方法、默認方法(略)

4.接口中不能定義構造器的!意味着接口不可以實例化

5.Java開發中,接口通過讓類去實現(implements)的方式來使用.如果實現類覆蓋了接口中的所有抽象方法,則此實現類就可以實例化;如果實現類沒有覆蓋接口中所有的抽象方法,則此實現類仍為一個抽象類

6.Java類可以實現多個接口 --->彌補了Java單繼承性的局限性格式:class AA extends BB implements CC,DD,EE

7.接口與接口之間可以繼承,而且可以多繼承

8.接口的具體使用,體現多態性

9.接口,實際上可以看做是一種規范

面試題:抽象類與接口有哪些異同?

  • 1.接口使用上也滿足多態性
  • 2.接口,實際上就是定義了一種規范
  • 3.開發中,體會面向接口編程!

類的內部成員之五:內部類

1.Java中允許將一個類A聲明在另一個類B中,則類A就是內部類,類B稱為外部類

2.內部類的分類:成員內部類(靜態、非靜態) vs 局部內部類(方法內、代碼塊內、構造器內)

3.成員內部類:

一方面,作為外部類的成員:

調用外部類的結構

可以被static修飾

可以被4種不同的權限修飾

另一方面,作為一個類:

類內可以定義屬性、方法、構造器等

可以被final修飾,表示此類不能被繼承。言外之意,不使用final,就可以被繼承

可以被abstract修飾

4.關注如下的3個問題

  • 4.1 如何實例化成員內部類的對象
  • 4.2 如何在成員內部類中區分調用外部類的結構
  • 4.3 開發中局部內部類的使用 見《InnerClassTest1.java》

    //創建Dog實例(靜態的成員內部類):
    Person.Dog dog = new Person.Dog();
    dog.show();
    //創建Bird實例(非靜態的成員內部類):
    //Person.Bird bird = new Person.Bird();//錯誤的
    Person p = new Person();
    Person.Bird bird = p.new Bird();
    bird.sing();
    

day16

Error:

Java虛擬機無法解決的嚴重問題。如:JVM系統內部錯誤、資源耗盡等嚴重情況。比如:StackOverflowError和OOM。

一般不編寫針對性的代碼進行處理。

java.lang.Throwable

  • java.lang.Error:一般不編寫針對性的代碼進行處理。
  • java.lang.Exception:可以進行異常的處理

編譯時異常(checked)

IOException

FileNotFoundException

ClassNotFoundException

運行時異常(unchecked,RuntimeException)

NullPointerException

ArrayIndexOutOfBoundsException

ClassCastException

NumberFormatException

InputMismatchException

ArithmeticException

一、異常的處理:抓拋模型

過程一:"拋":程序在正常執行的過程中,一旦出現異常,就會在異常代碼處生成一個對應異常類的對象,並將此對象拋出。一旦拋出對象以后,其后的代碼就不再執行。

關於異常對象的產生: ① 系統自動生成的異常對象 ② 手動的生成一個異常對象,並拋出(throw)

過程二:"抓":可以理解為異常的處理方式:① try-catch-finally ② throws

二、try-catch-finally的使用

try{
        //可能出現異常的代碼

}catch(異常類型1 變量名1){
//處理異常的方式1
}catch(異常類型2 變量名2){
//處理異常的方式2
}catch(異常類型3 變量名3){
//處理異常的方式3
}
....
finally{
//一定會執行的代碼
}

說明:

1.finally是可選的。

2.使用try將可能出現異常代碼包裝起來,在執行過程中,一旦出現異常,就會生成一個對應異常類的對象,根據此對象的類型,去catch中進行匹配

3.一旦try中的異常對象匹配到某一個catch時,就進入catch中進行異常的處理。一旦處理完成,就跳出當前的try-catch結構(在沒有寫finally的情況)。繼續執行其后的代碼

4.catch中的異常類型如果沒有子父類關系,則誰聲明在上,誰聲明在下無所謂。 catch中的異常類型如果滿足子父類關系,則要求子類一定聲明在父類的上面。否則,報錯

5.常用的異常對象處理的方式: ① String getMessage() ② printStackTrace()

6.在try結構中聲明的變量,再出了try結構以后,就不能再被調用

7.try-catch-finally結構可以嵌套

  • 體會1:使用try-catch-finally處理編譯時異常,是得程序在編譯時就不再報錯,但是運行時仍可能報錯。相當於我們使用try-catch-finally將一個編譯時可能出現的異常,延遲到運行時出現。

  • 體會2:開發中,由於運行時異常比較常見,所以我們通常就不針對運行時異常編寫try-catch-finally了。針對於編譯時異常,我們說一定要考慮異常的處理。

try-catch-finally中finally的使用:

1.finally是可選的

2.finally中聲明的是一定會被執行的代碼。即使catch中又出現異常了,try中有return語句,catch中有return語句等情況。

3.像數據庫連接、輸入輸出流、網絡編程Socket等資源,JVM是不能自動的回收的,我們需要自己手動的進行資源的釋放。此時的資源釋放,就需要聲明在finally中。

異常處理的方式二:throws + 異常類型

1."throws + 異常類型"寫在方法的聲明處。指明此方法執行時,可能會拋出的異常類型。一旦當方法體執行時,出現異常,仍會在異常代碼處生成一個異常類的對象,此對象滿足throws后異常類型時,就會被拋出。異常代碼后續的代碼,就不再執行!

2.體會:try-catch-finally:真正的將異常給處理掉了。throws的方式只是將異常拋給了方法的調用者,並沒有真正將異常處理掉。

3.開發中如何選擇使用try-catch-finally 還是使用throws?

  • 3.1 如果父類中被重寫的方法沒有throws方式處理異常,則子類重寫的方法也不能使用throws,意味着如果子類重寫的方法中有異常,必須使用try-catch-finally方式處理。
  • 3.2 執行的方法a中,先后又調用了另外的幾個方法,這幾個方法是遞進關系執行的。我們建議這幾個方法使用throws的方式進行處理。而執行的方法a可以考慮使用try-catch-finally方式進行處理。

方法重寫的規則之一: * 子類重寫的方法拋出的異常類型不大於父類被重寫的方法拋出的異常類型

如何自定義異常類?

  • 1. 繼承於現有的異常結構:RuntimeException 、Exception
  • 2. 提供全局常量:serialVersionUID
  • 3. 提供重載的構造器


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM