异常概述
异常:代表程序出现的问题
误区:不是让我们以后不出异常,而是程序出了异常之后,该怎么处理。
异常的继承体系:
-
Error:代表的系统级别错误(属于严重问题)
系统一旦出现问题,sun公司会把这些错误封装成Error对象。
Error是给sun公司自己用的,跟我们没啥关系,不需要管。
-
Exception:异常,代表程序可能出现的问题。
我们通常会用Exception以及他的子类来封装程序出现的问题。
-
RuntimeException 以及它的子类:运行时出现的异常(如数组越界)
编译阶段不会出现异常提示。
-
其他异常:叫做编译时异常,编译阶段就会出现异常提示的。(如日期解析异常)
编译时异常:在编译阶段,必须手动处理,否则代码报错。目的是提醒程序员检查本地信息。
运行时异常:在编译阶段不需要处理,是代码运行时出现的异常。目的是:由于参数错误而导致的问题。
异常的作用:
- 异常是用来查询bug的关键参考信息。
- 异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况。
异常的处理方式
异常有三种处理方式分别为:
JVM默认的处理方式
- 把异常的名称,异常原因以及异常出现的位置等信息输出在控制台。
- 程序停止执行,异常下面的代码不会再执行。
自己处理(捕获异常)
捕获异常的目的:不让程序停止。
格式:
try{
可能出现异常的代码;
} catch(异常类名 变量名){
异常的处理代码;
}
目的:当代码出现异常时,可以让程序继续往下执行。
举例:
try{
//可能出现异常的代码
System.out.println(2/0);//这里出现了异常,程序就会在这里创建一个ArithmeticException对象
//new ArithmeticException();
//拿着这个对象到catch的小括号中进行对比,看小括号中的变量能否接收这个对象
//如果能接收,就表示这个异常被捕获(抓住),执行catch里面对应的代码
//当catch里面所有的代码执行完毕,继续执行try...catch体系下面其他代码
}catch(ArithmeticException e){
//如果出现了ArithmeticException异常,我该如何处理
System.out.println("算数异常");
}
使用情况:
-
如果try中没有遇到问题,那么就不会执行catch中的代码,而是执行try中代码。
-
如果try中遇到多个问题,会写多个catch与之对应
如果要捕获多个异常,这些异常中如果存在继承关系,那么父类一定要写在最下面。
在jdk7以后可以在catch中的同时捕获多个异常,中间用
|
隔开catch(ArrayIndexOutOfBoundsException | ArithmeticException e )
表示如果出现了A异常或B异常,采用同一种处理方案。public class Text { public static void main(String[] args){ int[] arr={1,2,3,4,5,6}; try{ System.out.println(arr[10]);//如果没有写多个catch System.out.println(2/0); String s=null; System.out.println(s.equals("abc")); }catch (ArrayIndexOutOfBoundsException e){ System.out.println("索引越界"); }catch (ArithmeticException e){ System.out.println("算数异常"); }catch (NullPointerException e){ System.out.println("空指针异常"); } System.out.println("看看我执行了么"); } }
上面这么多catch,只能输出第一个捕获到异常的catch中的代码。
建议按照try中代码顺序依次写catch捕获对应的异常,增强可读性。
-
如果try中遇到的问题没有被捕获,即catch中写的依次与实际引发的异常不一样,这样就会无法捕获到异常。
此时相当于try catch代码白写了,最终采用JVM进行默认处理。
-
如果try中遇到了异常,那么try下面的其他代码就不会执行了
public class Text { public static void main(String[] args){ int[] arr={1,2,3,4,5,6}; try{ System.out.println(arr[10]); System.out.println("这里不执行了");//这段代码就不会执行 }catch (ArrayIndexOutOfBoundsException e) { System.out.println("索引越界"); } System.out.println("看看我执行了么"); } }
异常中常用方法(Throwable的成员方法):
方法名 | 说明 |
---|---|
public String getMessage() | 返回异常的简短描述 |
public String toString() | 返回异常的详细描述 |
public void printStackTrace() | 把异常的错误信息输出在控制台 |
第三个方法虽然会把异常的所有信息打印在控制台和JVM默认处理方法一样,但是!!不会停止运行下面的代码
第三个方法包含了上面两个方法的信息,是最常用的。
第三个方法在底层利用System.err.println进行输出,在控制太显示红色字体
交给调用者处理(抛出异常)
抛出异常的目的:告诉方法调用者这个方法出错了!
方法抛出异常要写两个部分:
-
throws
写在方法定义处,表示声明一个异常。告诉调用者,使用本方法可能有哪些异常。
如果是编译时异常:必须要写
如果是运行时异常:可以省略不写
public void 方法() throws 异常类名1,异常类名2,....{ }
-
throw
写在方法内,结束方法。手动抛出异常对象,交给调用者。方法中下面的代码不再执行了。
public void 方法(){ throw new NullPointerException(); System.out.println("这部分代码不会执行"); }
-
完整写法
public void 方法() throws 异常类名1,异常类名2,...{//如果是runtime异常可以不写 throw new NullPointerException(); System.out.println("这部分代码不会执行"); }
举例:
//写一个获取数组最大元素的方法
public int getMax(int[] arr){
if(arr==null){
//此时抛出异常
throw new NullPointerException;
}
if(arr.length==0){
throw new ArrayIndexOutOfBoundsException();
}
int max=arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i]>max){
max=arr[i]
}
}
return max;
}
public class Text {
public static void main(String[] args){
int[] arr=null;
int max=0
try{
max=getMax(arr);//将调用方法的代码用try进行捕捉,要不然下面的代码将无法执行。
}catch(NullPointerException e){//空指针异常
e.printStackTrace();
}catch(ArrayIndexOutOfBoundsException e){//索引越界异常
e.printStackTrace();
}
}
}
自定义异常
写法:
-
定义异常类
-
写继承关系
如果是运行时异常:继承
RuntimeException
如果是编译时异常:继承
Exception
-
空参构造
-
带参构造
自定义异常的意义:让控制台的报错信息更加见名知意。
可以在Catch中捕捉哪些java中没有定义的比如说名字规范等情况。
自定义异常的规范写法:
public class NameFormatException{}
//NameFormat:异常名字
//Exception:表示这是一个异常类
//使用大驼峰命名法
举例:
public class NameFormatException extends RuntimeException{//姓名格式异常(自定义的)(idea快捷键alt+insert自动补齐即可)
public NameFormatException() {
}
public NameFormatException(String message) {//传入异常的信息
super(message);
}
}
标签:System,try,println,catch,异常,public
From: https://www.cnblogs.com/wdadwa/p/17281539.html