(一)異常處理
異常的處理方式:
方式一:捕獲處理
捕獲處理的格式:
try{
可能會發生異常的代碼
}catch(異常的類型 變量名){
異常處理代碼;
}
捕獲處理要注意的細節:
1.如果一個try塊的代碼出現了異常,經過處理之後,那麼try-catch塊外面的代碼可以正常執行。
2.如果一個try塊的代碼出現了異常,那麼在try塊中出現異常的代碼後面的所有代碼都無法正常執行。
3.一個try塊後面可以跟有多個catch塊,也就是說一個try塊可以捕獲多種異常的類型。
4.一個try塊後面可以跟有多個catch塊,但是捕獲的異常類型必須按照從小到大進行捕獲,否則後面的沒有進行的機會。(是廢話,編譯出錯。)
方式二:拋出處理(關鍵字:throw throws)
拋出處理要注意的細節:
1.如果一個方法的內部拋出了一個編譯時異常對象,那麼必須要在方法中聲明拋出。
2.如果調用了一個聲明拋出編譯時異常類型的方法,那麼調用者必須要進行處理,否則編譯報錯。
3.一個方法如果遇到了throw關鍵字,那麼該方法會馬上停止執行。
4.一種情況只能拋出一種異常類型。
throw 與throws的區別:
1.throw關鍵字是用於在一個方法的內部拋出異常對象的,throws是用於在方法上聲明拋出異常類型的。
2.throw關鍵字後面跟的是異常的對象,throws後面跟的是異常的類型。
3.throw關鍵字一次只能拋出一個異常對象,throws關鍵字一次可以聲明拋出多種異常類型。
什麼時候使用拋出處理?什麼時候使用捕獲處理?
如果需要通知調用者出現異常,使用拋出處理。
如果與用戶打交道的代碼出現異常,使用捕獲處理,千萬不能拋出。
例如:
class demo1
{
public static void main(String[] args) //throws Exception//拋出給Java虛擬機處理
{
//main方法調用了聲明拋出異常類型的div方法,那麼main必須進行處理(捕獲處理或拋出處理)
//或者用try-catch自己處理
try{
div(8,2,null);
}catch(Exception e){//捕獲後,處理
System.out.println("++++++");
}
System.out.println("========");
}
public static void div(int a,int b,int[] arr)throws Exception,NullPointerException{//方法內部拋出了一個異常對象,必須在方法上聲明拋出異常類型
if(b==0){
throw new Exception();//拋出異常對象給調用者div
//System.out.println(">>>>>>>>");//throw後面的語句不可能執行,相當於廢話,編譯報錯
}else if(arr==null){
throw new NullPointerException();
}
int c=a/b;
System.out.println("結果是:"+c);
}
}
Throwable:所有異常與錯誤的終極父類
Error:錯誤一般都是由於jvm或者硬件引發的問題,所以一般不會通過代碼處理。
Exception:異常 如果程序出現了異常,那麼一般就需要通過代碼去處理了。
運行時異常 (RuntimeException及其子類) :如果一個方法內部拋出了一個運行時異常對象,那麼方法聲明可以聲明拋出也可以不聲明拋出異常類型,如果調用了一個聲明拋出運行時異常類型的方法,那麼調用者可以處理也可以不處理。
編譯時異常 (非運行時異常,受檢異常) :如果一個方法內部拋出了一個編譯時異常對象,那麼方法必須要聲明拋出異常類型,如果調用了一個聲明拋出編譯時異常類型的方法,那麼調用者必須要處理。
爲什麼java編譯器對運行時異常管理得如此寬鬆呢?
因爲運行時異常時是可以通過程序員良好的編程習慣避免發生的。
3.自定義異常
自定義一個類繼承Exception。
例如:
/*
模擬去喫臭豆腐,帶夠十塊錢,可以喫到香噴噴的臭豆腐,不夠就跑出沒有帶夠錢的異常。
*/
class LessMoneyException extends Exception
{
public LessMoneyException(String message){
super(message);
}
}
class demo4
{
public static void main(String[] args)
{
int money;
try{
Choutofu(5);
}catch(LessMoneyException e){
e.printStackTrace();
System.out.println("哎,下次再來,,,");
}
}
public static void Choutofu(int money)throws LessMoneyException{
if(money<10){
throw new LessMoneyException("錢不夠,喫不起???");
}else{
System.out.println("臭豆腐真香!!!");
}
}
}
(二)finally塊
使用前提:必須要配合try塊使用,不能單獨使用。
finally塊的代碼在任何情況下都可以執行,只有在jvm退出的時候不能執行。
try塊的表現形式有三種:
方式一:適用於沒有資源文件釋放,只需要處理異常的代碼。
try{
可能發生異常的代碼;
}catch(異常類型 e){
異常處理的代碼
}
方式二:適用於既有資源釋放也需要處理異常的代碼。
try{
可能發生異常的代碼;
}catch(異常類型 e){
異常處理的代碼
}finally{
釋放資源的代碼;
}
方式三:適用於只需要釋放資源文件,不需要異常處理的代碼。
try{
可能發生異常的代碼;
}finally{
釋放資源的代碼;
}
例如:
import java.io.*;
class demo6
{
public static void main(String[] args)
{
FileReader fileReader=null;
try{
//第一步找到目標文件
File file=new File("E:\\a.txt");
//第二步:建立文件 與程序的數據輸入通道
fileReader=new FileReader(file);
//讀取文件數據
int content=0;
while((content=fileReader.read())!=-1){//如果沒有讀取到文件的末尾就繼續讀取
System.out.print((char)content);
}
}catch(IOException e){
System.out.println("讀取文件失敗。。");
}finally{
//可能釋放資源失敗,表示根本沒有權限操作文件,就不用再關了
try{
//關閉資源 (釋放資源文件)
fileReader.close();//不管怎樣,都會關閉資源
System.out.println("釋放資源成功!!");
}catch(IOException e){
System.out.println("釋放資源失敗!!");
}
}
}
}
(三)包
兩個java文件中存在同名的類,那麼後編譯的class文件會覆蓋之前的class文件。
包:java中的包相當於windows中的文件夾。
包的好處:
1.解決類名重複class文件覆蓋的問題。
2.方便軟件版本的發佈。
包語句的格式:
package 包名;
在編譯時加上 -d 參數,會新建一個文件夾
格式:
javac -d 存放class文件的路徑 java源文件名(.表示當前路徑,..是父路徑,/是根路徑)
包要注意的事項:
1.一個java文件如果有了包語句,那麼該類文件的完整類名是“包名+類名”。
2.一個java文件只能有一個package語句。
3.package語句必須位於java文件中的第一個語句。
有了包之後類與類之間的訪問:
導包語句的作用:簡化書寫
導包語句的格式:
import 包名.類名。
注意細節:
1.一個java文件可以出現多個import語句。
2.導包時可以使用*通配符來匹配類名,*可以匹配任何類名。
3.import a.*;該語句不會作用於a包下面的子包。
推薦:不要使用通配符導包,因爲結構不清晰。
jvm加載class文件是屬於懶惰型加載,只有使用到了該類文件的時候纔會被加載到內存。import導包並不會使class文件被加載到內存。
一個類文件被加載到內存的時候,會加載靜態代碼塊的代碼。
什麼時候需要導包語句呢?
類與類之間的訪問,如果兩個類不屬於同一個包,就要用導包語句。
java.lang包中的類,jvm會自動導入。
包名命名規範:全部小寫。
package bb;
import aa.demo10;//導入aa包中的demo10
public class demo9
{
public static void main(String[] args)
{
demo10 c=new demo10();
c.print();
//System.out.println("Hello World!");
}
}
package aa;
public class demo10
{
public void print(){
System.out.println("這是demo10的print方法");
}
}
(四)權限修飾符
訪問權限修飾符:用於控制修飾的類、變量、方法的可見範圍。
public protected default(表示沒有權限修飾符) private (從大到小排序)
同一個類 true true true true
同一個包 true true true false
子父類 true true false false
不同的包 true false false false
注意:在不同包中類與類之間可以訪問的權限修飾符只有public protected可以訪問,但是protected必須要在
繼承關係下才能使用。