1. 程式人生 > >枚舉、異常

枚舉、異常

棧跟蹤 操作 null found type 隱藏 demo eof args

1.訪問權限修飾符 enum 枚舉名{
//靜態常量
常量A,常量B,常量C;

}
2.枚舉只能給枚舉對象賦值
枚舉名 對象 = 枚舉名.常量A;
對象存儲的就是枚舉值
3.switch...case形式
switch(對象|枚舉名.常量A){
//枚舉中定義的常量
case 常量A:
執行語句;
break;
........
}
通過反編譯:
其實枚舉即使一個特殊的類並且默認繼承一個Enum的類
提供一些我們常用的方法 -->通過API中的Enum類就可以看到
兩個隱藏方法values() --> 可以獲取一個枚舉中所有常量值的數組
valueOf("常量A")-->參數是一個字符串名就可以了 需要是枚舉中常量的名字

所寫的枚舉常量 public static final 枚舉類型 常量名;
構造方法私有化
枚舉單利:
public enum 枚舉名{
常量A;

}
可以在枚舉中定能定義靜態方法靜態屬性和成員方法和成員屬性
枚舉中可以定義抽象方法,但是若枚舉中有枚舉常量抽象方法需要定義在枚舉常量的下面,並且必須實現這個抽象方法
常量是可以有自己的方法的形式的
public enum 枚舉名{
A{
重寫抽象方法
};
public abstract 返回值類型 方法名();


}


異常:
非正常發生的事情,不同於尋常
一個正常人,身體發熱,去看醫生,說不意思:你感冒了
ps:程序出問題了給的警告

/**
 * 
 */
package com.qfedu.Day15.Exception;

public class ExceptionDemo {

    public static void main(String[] args) {
        System.out.println("-----------------------begin-----------------------");
        int x = 9;
        int y = 0;
        try {
        //這段代碼可能會出現異常
        int result = x/y;
        System.out.println(
"結果:"+result); //1.若能明確異常類型,就寫當前異常類型 //2.不知道異常類 --> Exception }catch(ArithmeticException e) { System.out.println("除數為0,出現了問題!!!!!!"); } System.out.println("-------------------------end-------------------------"); } }


異常的種類:
編譯時異常:在代碼進行編譯階段,就會出現的異常信息
編譯時異常必須處理,不處理程序會一直報錯,若強行運行只有崩潰的結果
運行時異常:在代碼執行階段,出現異常就是運行時異常
1.在寫代碼時,就知道這段代碼會出現一個異常進行一些處理
2.拋出異常後,在進行修改

/**
 * 
 */
package com.qfedu.Day15.Exception;

public class ExceptionDemo2 {

    public static void main(String[] args) {
//        String num1 = "10";
//        String num2 = "0";
//        try {
//        int i1 = Integer.parseInt(num1);
//        int i2 = Integer.parseInt(num2);
//        int result = i1/i2;
//        System.out.println(result);
//        }catch(NumberFormatException e) {
//            //打印異常信息 --> 打印系統所自訂的異常信息
//            System.out.println(e.getMessage());
//        }catch (ArithmeticException e) {
//            /*
//             * java.lang.ArithmeticException: / by zero
//                at com.qfedu.Day15.Exception.ExceptionDemo2.main(ExceptionDemo2.java:23)
//             */
//            //打印跟中棧信息
//            e.printStackTrace();
//        }
        //如下語法需要註意
//        String num1 = "10";
//        String num2 = "0";
//        try {
//        int i1 = Integer.parseInt(num1);
//        int i2 = Integer.parseInt(num2);
//        int result = i1/i2;
//        System.out.println(result);
//        
//        }catch (ArithmeticException e) {
//            /*
//             * java.lang.ArithmeticException: / by zero
//                at com.qfedu.Day15.Exception.ExceptionDemo2.main(ExceptionDemo2.java:23)
//             */
//            //打印跟中棧信息
//            e.printStackTrace();
//        //Exception是父類---> 接收所有異常,剩余的子類異常就無法接收異常信息了    
//            //所以父類異常需要出現在子類異常的後面
//        }catch(Exception e) {
//            //打印異常信息 --> 打印系統所自訂的異常信息
//            System.out.println(e.getMessage());
//        }
        //1.7中的新特性
        String num1 = "10";
        String num2 = "0";
        try {
        int i1 = Integer.parseInt(num1);
        int i2 = Integer.parseInt(num2);
        int result = i1/i2;
        System.out.println(result);
        //平級捕獲異常 需要滿足 父類不能出現在子類的前面
        }catch (ArithmeticException | NumberFormatException e) {
            //打印跟中棧信息
            e.printStackTrace();
        }
        
    }

}


/**
*
*/
package com.qfedu.Day15.Exception;


public class ExceptionDemo3 {


public static void main(String[] args) {
System.out.println("-----------------------begin-----------------------");
int x = 9;
int y = 0;
try {
//這段代碼可能會出現異常
int result = x/y;
System.out.println("結果:"+result);
//1.若能明確異常類型,就寫當前異常類型
//2.不知道異常類 --> Exception
}catch(ArithmeticException e) {
System.out.println("除數為0,出現了問題!!!!!!");
//System.exit(1);
//finally優先於return執行
//finally只有使用停止JVM的方法時才不執行
}finally {

System.out.println("關閉資源,finally語句被執行了..");

}
System.out.println("-------------------------end-------------------------");

}
}

/**
*
*/
package com.qfedu.Day15.Exception;


public class ExceptionDemo4 {


public static void main(String[] args) {
System.out.println(Result1());// 3
//System.out.println((int)(Math.random()*5));
System.out.println(Result2());
}
public static int Result1() {
int x = 9;
int y = 3;
int result = 0;
try {
result = x/y;
return result;

}catch(ArithmeticException e) {
return Integer.MAX_VALUE;
}finally {
result++;
System.out.println("result="+result);// 1 / 4
}


}
public static int Result2() {

try {

return 1 ;
}finally {

//語法:只有finally當中存在return語句,永遠返回的是fianlly中的結果,要避免這樣發生
return 100;
}
}

}




異常的分類:
所有異常的根類Throwable
知道其兩個子類 Error 和 Exception
程序猿所處理的是Exception的異常
Error程序猿不處理 --> JVM所出現的錯誤

Exception --> 編譯時異常
RuntimeException -->運行是異常

常見異常:
--------------------------------------------------------------------------------------------
NullPointerException 空指針異常 String str = null;
str.charAt() == null.charAt();
ArrayIndexOutOfBoundsException 數組下標越界異常 int[] array ={1,2};
array[100]
StringIndexOutOfBoundsException 字符串下標越界異常 String str ="ab";
str.charAt(10);
NumberFormatException 數據類型格式化異常 new Integer("11a");

ClassCastException 強制類型轉換異常 一個父類對象在進行向下轉型時
Animal a = new Dog();
Cat cat =(Cat)a
IOException 流異常 流使用錯誤

處理異常:

異常的特點:
若某行代碼在執行過程中拋出異常,那麽後面的代碼就會不執行了(運行時和編譯時都出現這個問題)
若需要據需執行或打印其他方式-->就需要處理掉當異常了

1.try...catch...finally
1.1try...catch
try是捕獲異常 catch抓取出捕獲的異常

try{
編譯可能出現異常的代碼
}catch(異常類型 e){ --->定義了一個異常類型的變量
//記錄日誌
//直接打印異常信息
//繼續拋出異常
ps:無論在catch代碼代碼段中做任何事情,都是對異常的一種補救措施


/**
*
*/
package com.qfedu.Day15.Exception.ThrowAndThrows;


public class ThrowsDemo {
//後果:main已經是最終的位置,若在main中繼續拋出異常,接受者只有一個JVM
//得到的結結果就是在控制臺上打印跟中棧信息
//ps:throws主要的作用就是提示調用者有異常需要處理,一般會和編譯時異常一起使用
public static void main(String[] args)throws NumberFormatException {

String str = "123a";

//正確的做法就是需要處理這個異常try...catch
//但是處理異常還有一種方法繼續throws
int num = getResult(str);

}
public static int getResult(String value)throws NumberFormatException {
return new Integer(value);
}
}



/**
* */ package com.qfedu.Day15.Exception.ThrowAndThrows; import java.io.FileInputStream; import java.io.FileNotFoundException; import javax.management.RuntimeErrorException; public class ThrowDemo { public static void main(String[] args)throws FileNotFoundException { //效果等同於return //throw new RuntimeException(); String str = "123a"; try { int num = getNumber(str); }catch (NumberFormatException e) { System.out.println(e.getMessage()); } try { new FileInputStream("C:\\test"); } catch (FileNotFoundException e) { //1.7使用throw拋出一個異常對象,throw new 異常類型() //1.7之後增強語法catch中是不是已將獲知異常類型而e是不是就是異常對象 //throw可以直接在catch語句塊中直接將異常對象拋出 //ps:若這樣使用就無法自定義信息了 //throw new FileNotFoundException(); throw e; } // int i = 0; // while(true) { // if(i == 200000) { // //最好不要 // throw new RuntimeException("循環已經停止"); // } // i++; // // } } public static int getNumber(String value) { try { return new Integer(value); }catch(NumberFormatException e) { throw new NumberFormatException("轉換錯誤,你輸入的是什麽???"); } } }


}
總結:
1.若try語句塊中出現異常,那麽異常代碼後的代碼都不會執行,會直接跳轉到catch語句塊中執行
2.若try語句塊中沒有出現異常會繼續執行,catch語句塊將不會執行

catch語句塊中處理異常的方法:
getMessage():捕獲異常信息的描述,提示用戶異常信息是什麽
System.out.println(e.getMessage());
toString():捕獲異常信息藐視以字符串的形式返回(不用)
System.out.println(e.toString());
printStackTrace()打印異常棧跟蹤信息並輸出到控制臺上
ps:這個方法有一個重載,參數是輸出流,指定輸出的位置
基本上即使在處理日誌--> 雷軍 --> 人們最常問的的問題10個 --> Top N
一般來說我們都會在catch語句塊中進行這個方法的調用並打印信息
主要用於:看到異常類型,異常原因,異常出現的位置,在開發調用和測試的過程中來進行使用
在完成項目進行提交時會做如下操:
1.改變輸出作為日誌存在
2.直接刪除異常跟中信息,轉而使用輸出語句
看ExceptionDemo
若在執行代碼中出現多個異常
多種類型異常處理:
try{
編寫可能出現的代碼異常
}catch(異常類型 e){
進行處理異常

}catch(異常類型 e){
進行異常處理

}....
//連級判斷-->異常和異常之間有一定關聯性 --> 反射的時候

//1.7新特性
看ExceptionDemo2

finally代碼塊
finally語句開表示最終的,無論如何都會執行(異常捕獲是夠成功與否)
finally語句塊的作用:
通過try...catch的形式可以捕捉一些異常,某些時候例如:
我們在對一些物理資源(磁盤文件/網絡連接/數據庫連接),fianlly會進行資源釋放和關閉操作
IO流中
捕獲異常終極寫法
try{
編譯代碼可能出現的異常
}catch(異常類型 e){ --> catch可以有多個
輸出異常信息
}finally{ --> 只能有一個 在沒有資源釋放或關閉的情況下fianlly語句塊可以省略
釋放資源
}
看ExceptionDemo3
面試題:
看ExceptionDemo4
final , finally ,finalize 的區別


2.throw 和 throws
throw語法:
運用於方法的內部,拋出一個具體的異常對象
throw new 異常類型("異常信息"); -->等同於 return 可以讓方法結束

throw作用:
當一個方法出現不正常的情況的時候,我們不知道該方法返回什麽,此時就返回一個錯誤.
在catch語句塊中繼續向上拋出異常
return 是返回一個值 throw是返回一個錯誤,返回給該方法的調用者
throw創建一個異常對象並定義異常信息,用於傳遞給調用者
看ThrowDemo


throws語法:
定義於方法聲明之上,用於表示當前方法不處理異常,而是提醒該方法的調用者來處理異常

設計當前throws拋出異常,在方法體中的所有異常你都不需要處理,在調用方法時必須處理當前拋出
的異常
throws使用需要謹慎,不要大批量隨意拋出異常,只要處理時機不成熟的時候,才選擇拋出

ps:
若是在main方法中拋出異常是完全可以的,但是在main方法中拋出異常會失去我們程序猿的作用!!
看ThrowsDemo


throw和throws的不同
throw:運用於方法內部,用於給調用者返回一個異常對象,和return一樣會結束當前方法
throws運行於方法聲明之上,用於表示當前方法不處理異常,而是提醒該方法的調用者來處理異常(拋出異常)
若throw創建的對象是編譯時異常(Exception)那麽在方法中需要使用throws或try...catch來處理
throws需要在定義在方法使用

自定義異常
系統中所提供的異常不能滿足所有的需求時,此時我們可以定義自己異常
分兩種:
1.當前異常是在程序運行時出現異常-->繼承與RuntimeException
2.當前異常是在代碼書寫時就出現異常-->繼承Exception

異常連和異常轉換
異常轉換:當位於最上層子系統不需要關系底層異常的細節時,常量的做法就是當前捕獲的原有異常進行一個新
包裝,使之成為一個全新的異常,然後在拋出
異常鏈:把原始的異常包裝為新的一行,從而行程多個異常的存在,並且排列,有助於我們查找異常信息

數據結構:
數據結構是計算存儲,組織數據的方式
編程 = 數據結構 + 算法
數據結構存在著多種關系,一對一 一對多 多對多 等等
常見的數據結構
數組,棧,鏈表,哈希表,隊列,堆,樹,圖
java中集合框架其實就是數據結構的實現與封裝
java中的集合根據使用不同的數據結構各種性能是不一樣
最簡單的就是數組 -->線性結構
ps:大話數據結構
需求:
模擬一個球員系統你是教練
1.初始容量為5的線性列表,準備用來存儲場上的5個球員的號碼
2.安排5個球員上場[11,22,33,44,55];
3.查詢指定位置的球員的球衣號碼是多好,查詢索引2號碼應該333
4.根據球衣號碼查詢該球員在場上的索引位置 44 ---> 3
5.替換場上所以位置為2的球員,替換之後該位置的球衣編號為333
6.替換球衣號碼為22的球員 ,替換之後為222
7.把場上所以位置為2的球員罰下(即沒有替補)
8按照球員在場上的位置打印球衣號碼風格[11,22,33,44,55]
修改需求:
健壯性和安全性的修改
1.創建數組的時候 是不是可以傳入一個負數
2.查找是會出現負數和大於數組長度的值
3.若我們需要添加元素,因為我們的大小是5個元素,擴充數組

Java就提供一個類是與我們封裝的類的一種
集合:存儲的是對象,不能存儲值類型
集合是變長
集合提供了一些常用方法,讓我們來進行增刪改查等操作
List(列表):集合中的對象是按照索引位置存儲的(有序),並且可以存儲重復數據
Set(集):集合中的對象沒有特定存儲方法(無序-->無序不等於隨機),並且不允許重復
Map(映射):集合中每一個元素都包含一對"鍵值對"key和value形式,不允許key重復,value可以重復


ArrayList集合:

/**
 * 
 */
package com.qfedu.Day15.ArrayList;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArrayListDemo {
        @SuppressWarnings("rawtypes") //註解
        public static void main(String[] args) {
            //1.無參
            ArrayList al = new ArrayList();
            //2.有參 --> 指定初始容量大小
            ArrayList al2 = new ArrayList(20);
            //3.通過構造方法在ArrayList集合當中存另外一個集合的元素
            ArrayList al3 = new ArrayList(al2);
            //常用方法:
            //向集合中添加元素
            al.add(1);
            al.add(2.1243);
            al.add("3");
            al.add(‘c‘);
            al.add("我可以存儲任何數據類型");
            //因為ArrayList底層實現是數組,所以存在下標的概念
            //第一個元素的位置是0,最後一個元素的位置是size-1
            //集合可以直接打印對象-->重寫了toString
            System.out.println(al);
            //向集合中添加指定元素
            al.add(1, "我是插入值");
            System.out.println(al);
            
            //向集合中插入另外一個集合
            al2.add("2018");
            al2.add(8);
            al2.add(17);
            //向集合中添加原有集合的值
            al.addAll(al2);
            System.out.println(al);
            //向指定位置添加集合
            //addAll(int index, Collection<? extends E> c) 
            
            //清空集合-->沒有數據,集合還存在
            al2.clear();
            System.out.println(al2);
            
            //判斷集合中是否存在指定元素
            //true 就是存在 false是不存在
            System.out.println(al.contains("2018"));

            //通過下標獲取集合中的元素
            System.out.println(al.get(1));
            
            //判斷集合中首次出現指定元素的位置
            //如果找到就返回其下標(第一次)
            //沒有找到 -1
            System.out.println(al.indexOf("七夕"));
            
            //判斷集合中是否存在元素(判斷集合是不是空的)
            //true 空   false 有元素
            System.out.println(al.isEmpty());
            
            //返回集合中最後一次出現元素的位置
            //如果找到了返回值下標(最後一次)
            //返回-1
            System.out.println(al.lastIndexOf(17));
            
            //刪除集合中的元素
            //根據下標刪除指定位置的元素
            al.remove(1);
            System.out.println(al);
            
            //根據傳入的指定元素刪除
            //若集合中存在著兩個相同的元素
            //刪除第一次出現的,若集合中沒有要刪除的元素
            //得到一個返回值false --> 刪除失敗沒有這個元素
            al.remove("2018");
            System.out.println(al);
            
            //傳入指定位置替換指定的值
            al.set(0, "我是替換值");
            System.out.println(al);
            
            
            //將ArrayLis集合轉換為數組,數組必須是Object
            Object[] array = al.toArray();
            System.out.println(Arrays.toString(array));
            //將數組轉換為List集合
            List al4 = Arrays.asList(array);
            
            
        }
}































枚舉、異常