《JAVA編程思想》第十二、十三、十四章節總結

第十二章

這一章節就講解了JAVA中的整個異常體系

 

一.異常

異常指的就是程序在執行過程中,出現的非正常的情況,最終會導致JVM的非正常停止。

java.lang.Throwable類是java語言中所有錯誤或者異常的超類。在這個類下面就有一個Error(錯誤)還有一個Exception(異常)。

異常下面又分爲幾種不同異常。其中最主要的就是RuntimeException(運行期異常)。

二.throw關鍵字

作用:可以使用throw在指定方法中拋出指定的異常。

格式:throw new ....Exception(“異常的原因”)

throws語句用在方法定義時聲明該方法要拋出的異常類型,如果拋出的是Exception異常類型,則該方法被聲明爲拋出所有的異常。多個異常可使用逗號分割。拋出幾個異常就必須在方法定義後面寫明拋出幾個異常。

 methodname throws Exception1,Exception2,..,ExceptionN  {  }  

再看throw和throws具體怎麼用: throws是在方法定義後面使用,而throw是在方法內部使用

package org.axc.com.Action;

import java.lang.Exception; 
public class TestException { 
    public static void count(int x) throws MyException{
        if(x>0) {
            throw new MyException("發生了自定義的異常");
        }
    }
    
    public static void main(String[] args) {
//      自己定義的異常如下
        try {
            count(3);
        } catch (MyException e) {
            e.printStackTrace();
        }
        
//      通過try-catch正常觸發的異常
        try {
            int num=1/0;
        }catch(Exception e) {
            System.out.println(e);
        }
    }
} 

throw(非throws)注意事項:

1.throw關鍵字必須寫在方法內部  2.throws關鍵字後邊new的對象必須是Exception或者Exception的子類對象

3.throw關鍵字拋出的指定的異常對象,我們就必須處理,要麼throws掉,要麼try catch

所以當我們在方法內部使用throw拋出異常之後,我們就必須處理這個異常了。

三.兩種處理異常的方式

1.throws拋出

將這個異常往上一級拋出,也就是方法的調用者處理(最終交給JVM處理,JVM會進行中斷處理)

格式就像下面的代碼,這裏是拋出一個,如果有多個就拋出多個

public static void count(int x) throws MyException{}

注意:1.throws關鍵字要寫在方法定義之後,也就是方法申明處

2.throws關鍵字後邊聲明的異常必須是Exception或者是Exception的子類

3.方法內部如果拋出了多個異常對象,那麼throws後邊必須也聲明多個異常。如果拋出的多個異常對象有子父類關係,那麼直接聲明父類異常即可。

4.調用了一個聲明拋出異常的方法,我們就必須處理這個異常。要麼繼續拋出,要麼try catch

2.try catch(自己處理異常)

格式:

 public static void main(String[] args) {
//      自己定義的異常如下
        try {
            count(3);
        } catch (MyException e) {
            e.printStackTrace();
        }
        
//      通過try-catch正常觸發的異常
        try {
            int num=1/0;
        }catch(Exception e) {
            System.out.println(e);
        }
    }

注意:1.可以使用多個catch來處理多個異常的情況

2.如果try中出現了異常,那麼就會執行catch中的異常處理邏輯。執行完畢後,不會再執行try後面的代碼,就直接執行try catch之後的代碼。所以這裏就要有finally(區分final,這不要搞混了)

四.finally關鍵字

當拋出異常的時候,剩餘的代碼就會終止執行,這時候一些資源就需要主動回收。Java 的解決方案就是 finally 子句——不管異常有沒有被捕獲,finally 子句裏的代碼都會執行。在下面的示例當中,輸入流將會被關閉,以釋放資源。

public static void main(String[] args) {
    InputStream is = null;
    try {
        is = new FileInputStream("沉默王二.txt");
        int b;
        while ((b = is.read()) != -1) {}
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        is.close();
    }
}

所以,finally關鍵字就是在這個代碼塊裏的代碼一定會被執行,不管出沒出現異常,所以一般情況下,這finally裏都是用來清理資源,釋放資源的。

五.Throwable類中3個異常處理的方法

1.String getMessage():返回此throwable的簡短描述

2.String toString():返回次throwable的詳細消息字符串

3.void printStackTrace() JVM打印異常對象,默認此方法打印的異常信息是最全面的。

第十三章

一.string 不可變 它爲什麼不可變?

在面試中經常遇到這樣的問題:1、什麼是不可變對象。不可變對象有什麼好處。在什麼情景下使用它,或者更具體一點,java的String類爲什麼要設置成不可變類型?

首先我們必須知道String類是不可變得,String類中每一個看似在修改它內容的方法,都是先創建一個副本在副本上進行操作,根本沒有對原始進行修改。再來說String對象爲什麼不可變,因爲不可變是最有效率和最安全的

相比於可變對象,不可變對象有很多優勢:

(1)不可變對象可以提高String Pool(字符串常量池)的效率和安全性。如果你知道一個對象是不可變動 ,那麼需要拷貝的對象的內容時就不用複製它本身二隻是複製它的地址,複製地址(通常一個指針的大小)需要很小的內存,效率也很好。

(2)不可變對象對於多線程是安全的,因爲在多線程同事進行的情況下,一個可變對象的值很可能被其他線程改變這樣會造成不可預期的結果麼人,使用不可變對象就可以避免這種情況出現。

二.String 類怎麼做到不可變得

       首先需要補充一個容易混淆的知識點:當使用final修飾基本類型變量時,不能對基本類型變量重新賦值因此基本類型變量不能被改變。但對於引用類型變量而言,它保存的僅僅是一個引用,final只保證這個引用變量所引用的地址不會改變即一直引用同一個對象,但這個對象完全可以發生改變。例如某個指向數組的final引用,它必須從此至終指向初始化時指向的數組,但是這個數組的內容完全可以改變。

        我們來看一下String類的兩個主要成員變量,其中value指向的是一個字符串數組,字符串中的字符就是用這個value變量存儲起來的,並且用final修飾,也就是說value一旦賦予初始值之後,value指向的地址就不能再改變了。雖然value指向的數組是可以改變的,但是String也沒有提供相應的方法讓我們去修改value指向的數組的元素。然而在StringBuilder中是提供了相應的方法讓我們去修改value指向的數組的元素,這也是StringBuilder的字符串序列可變的原因。

三. String類的操作

四.+ 和stringbuilder的關係

“+”可以連接兩個字符串,如下面代碼

String s = "abc"+"ddfa";

這樣也完成了添加的效果,同樣Stringbuilder類也有append()方法來添加。

使用“+”的時候,編譯期會自動引入Stringbuilder類,但是每一個String字符串,都會創建一個Stringbuilder類對象,所以效率低下,浪費空間。所以一般添加字符串要用Stringbuilder類。

 

五.stringBuilder和stringBuffer

StringBuilder類提供多種方法:append toString insert replace substring reverse delete 等各種方法,效率高,但線程不安全。

StringBuffer和StringBuilder基本差不多,效率低,但是線程安全。

第十四章

1.instanceof 和 isInstance區別

功能上沒有區別,兩者判定結果是完全一致的。只是在用法的格式上有區別

instanceof 是一個操作符,它的用法 :

  if (Obj a instanceof Class b) {
      //logic
  }

isInstance是一個方法,它的用法:

if(B.Class.isInstance(Obj a)){

}

2.反射   爲什麼要用反射

https://www.jianshu.com/p/9be58ee20dee

這篇博客已經總結非常詳細了

3.動態代理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章