异常处理
异常概述与异常体系结构(这里只针对Exception来说)
Exception:因编程错误或偶然的外在因素导致一般性问题,可以使用针对性的代码进行处理,例如:空指针的访问、试图读取不存在的文件、网络连接中断、数组角标越界、用户输入非法数据
//异常类阶级
java.lang.Object
java.lang.Throwable//(所有异常的父类)
/*
Throwable表示的范围要比Exception大。实际上程序使用Throwable来进行处理,没有任何语法问题,但是却会存在逻辑问题。因为此时出现的(或者说用户能够处理的)只有Exception类型,而如果使用Throwable接收,还会表示可以处理Error的错误,而用户是处理不了Error错误的,所以在开发中用户可以处理的异常都要求以Exception类为主。
*/
java.lang.Exception
RuntimeException//(这里可分为编译时异常(受检异常)和运行时异常(非受检异常)
编译时异常和运行时异常的区别
Java中异常被分为两大类:编译时异常(javac,exe、受检异常)和运行时异常(java,exe、非受检异常),也被称为受检异常和非受检异常,所有的RuntimeException类及其子类被称为运行时异常,其他异常都是编译时异常(栈溢出:StackOverFlowError和堆溢出:OutOfMemoryError)
异常机制用到的几个关键字:try、catch、finally、throw、throws。
-
try 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
-
catch 用于捕获异常。catch用来捕获try语句块中发生的异常。
-
//try-catch-finally(真正把异常处理掉了)(try-catch也可以嵌套) try{ //可能出现异常的代码;new 异常类型1(); }catch(异常类型1 变量名1){ 处理异常的方式 } catch(异常类型2 变量名2){ 处理异常的方式 } catch(异常类型3 变量名4){ 处理异常的方式 } //finally{ //一定会执行的代码放在这里面 } /* 注意: 1.把可能出现异常的代码放在try包装起来,一旦出现异常就会自动生成异常类对象,根据异常的对象去catch中进行匹配对应的异常类,找到后进行异常处理,一旦处理完成,就跳出catch结构(没写finally情况下)继续执行其后的代码 2.catch中的异常类型如果没有子父类关系,则声明位置无所谓;相反有子父类的关系,则要求子类一定声明在父类的上面,否则报错 3.常用异常处理:String getMessage()/printStackTrace(); 4.如果在try结构中声明的变量,出了try结构就不能被调用 5.finally一定会被执行的代码(无论有没有返回值)什么时候用finally,向数据库连接、输入与输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的释放,此时的资源释放就必须声明finally中 */ //范例: try{ inte[]arr={1,2,3}; sout(arr[3]); }catch(ArrayIndexOutOfBoundsException e){ //这里ArrayIndexOutOfBoundsException e=new ArrayIndexOutOfBoundsException e.printStackTrace(); } //这里的e.printStackTrace();又涉及到Throwable的成员方法
-
Throwable方法及说明 1 public String getMessage() 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了(返回异常原因) 2 public Throwable getCause() 返回一个Throwable 对象代表异常原因。 3 public String toString() 返回异常原因和异常类名 4 public void printStackTrace() 打印toString()结果和栈层次到System.err(返回异常类名、异常原因、异常位置信息) 5 public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。 6 public Throwable fillInStackTrace() 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。 -
finally finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
-
throw 用在方法内,跟的是异常对象名,表示抛出异常,由方法体内的语句处理,执行throw一定抛出了某种异常(指的是在方法中人为抛出一个异常对象(这个异常对象可能是自己实例化或者抛出已存在的)
//手动抛出异常
public class Text {
public static void main(String[] args) {
Student p=new Student();
p.regist(1221);
System.out.println(p);
}
}
class Student{
private int id;
public void regist(int id){
if(id>0){
this.id=id;
}else {
throw new RuntimeException("您输入的数据非法");//生成异常对象
}
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
'}';
}
}
-
throws 用在方法声明后面,跟的是异常类名,用于声明该方法可能抛出的异常。(**主方法上也可以使用throws抛出。**如果在主方法上使用了throws抛出,就表示在主方法里面可以不用强制性进行异常处理,如果出现了异常,就交给JVM进行默认处理,则此时会导致程序中断执行)由该方法的调用者去处理。(在方法的声明上使用,表示此方法在调用时必须处理异常)
-
//格式:throws+异常类型(向上抛策略,只是把异常抛给调用者,并没有将异常处理掉) public void method() throws FileNotFoundException,IOException{ //编译时异常出错代码 } //"throws+异常类型"写在方法声明处,指明此方法执行时,可能会抛出异常类型,如果出现异常,则会生成一个异常类的对象,此异常满足throws后异常声明类型时,会被抛出。异常代码后续的代码就不在执行了
运行时异常(unchecked、RuntimeException)(java.exe)
异常 | 描述 |
---|---|
NullpointerException | 空指针异常 |
ArrayIndexOutOfBoundsException | 用非法索引访问数组时抛出的异常 |
ClassCastException | 两个类型间转换不兼容时引发的异常 |
NumberFormatException) | 数字格式异常(数字格式化异常,需要查看字符串里面夹杂着string或者其他类型 |
InputMismatchException | 输入一个int数字,如果输入的是字符就会catch到InputMismatchException(输入不匹配) |
ArithmeticException | 算术异常 |
StringIndexOutOfBoundsException | 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小 |
受检异常(checked)
异常 | 描述 |
---|---|
ClassNotFoundException | 应用程序试图加载类时,找不到相应的类,抛出该异常。 |
IOException(FileNotFoundException) | 就输入输出异常,往往是在字符流、文件读或者写时发生的异常(一般会出现“拒绝访问”和“系统找不到指定路径”两种报错) |
方法重写的规则
子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
public class OverrideText{
public static void main(String[] args){
OverrideText p=new OverrideText();
p.display(new SubClass());//这里调用的是子类的方法
}
public void display(SuperClass s){
try{
s.method();
}catch(IOException e){
e.printStackTrace();
}
}
}
public void SuperClass{
public void method() throws IOException{
}
}
class SubClass extends SuperClass{
public void method()throws FileNotFoundException{
//这里算是方法重写,如果要加throws的话,异常类型要不大于父类(throws FileNotFoundException)
}
}
/*注意:
1.父类如果被重写的方法没有抛异常,子类重写的方法也不能抛异常(不能使用throws)如果子类有异常,必须使用try-catch-finally方式处理
2.执行方法a中,如果执行方法a中又调用了其他方法,且这几个方法是递进的关系,那么建议这几个方法使用throws的方式处理,而执行方法a可以考虑使用try-catch-finally方式进行处理
*/
自定义异常
/*
继承于现有的异常结果:RuntimeException、Exception
提供全局常量:serialVersionUID
提供重载的构造器
*/
//格式:
public class 异常类名 extends Exception{
//无参构造
//带参构造
}
//范例
public class MyException extends Exception {
static finally long serialVersionUID=-7034897193246939L;
public ScoreException(){
}
public ScoreException(String message){
super(message);
}
}