说明:
* 异常处理的方式二:使用"throws + 异常类型",声明在方法的声明处
*
* 1. 方法内根据可能产生的异常对象的类型,在方法的声明处使用throws的方法,抛出此异常的类型即可
* 2. 使用了throws的方式处理异常,并没有根本上解决异常,只是将异常抛给方法的调用者。
* 比如:method1()将异常抛给了method2()
* |---- java.lang.Error:Java虚拟机无法解决的严重问题。
* 如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性的代码进行处理。
* |---- java.lang.Exception:可以编写针对性的代码进行处理的
* |----编译时异常:在执行javac.exe命令时出现的异常
* |----IOException--
* |----FileNotFoundException--
* |----ClassNotFoundException--
* |----运行时异常(RuntimeException):在执行java.exe命令时出现的异常
* |----NullPointerException--空指针异常
* |----ArithmeticException--算术运算异常
* |----InputMismatchException--输入不匹配异常
* |----ArrayIndexOutOfBoundsException--数组下标越界异常
* |----ClassCastException--两给类型间转换时不兼容的异常
* |----NumberFormatException--数字格式化异常
*
一、Java中异常处理有两种方式:
* 1.try-catch-finally
* 2.throws的方式
* 二、 Java提供的是异常处理的抓抛模型。
* 过程一:"抛"
* > 在程序执行过程中,一旦出现异常,就会在出现异常代码的位置生成一个相应异常类的对象,并将此对象
* 向上抛出。
* > 异常对象一旦向上抛出,代码就不再继续向下执行。
* 过程二:"抓"
* > 可以理解为异常对象的处理过程。
* > 狭义上,理解为捕获异常,即为try-catch-finally的处理方法。
* > 广义上,理解为异常处理的两种方式:try-catch-finally ; throws
try{
* //可能出现异常的代码
*
* }catch(异常的类型1 变量名1){
* //异常的处理方式1
* }catch(异常的类型2 变量名2){
* //异常的处理方式2
* }...
*
* finally{
* //一定会被执行的代码
* }
- 说明:
* 1. finally结构是可选的。
* 2. 将可能出现异常的代码,使用try进行包裹,执行过程中,一旦生成异常对象,就将此对象抛出。在其后的catch中进行类型的匹配
* 3. 一旦异常对象与相应的某个catch中的异常类型匹配,则进入catch结构执行异常处理的操作。一旦执行完异常处理的操作后,直接跳出当前的try-catch结构。并执行其后的代码
* 4. 常见的异常处理的方式:
* ① 自定义输出的信息 ② 打印异常对象的message信息:getMessage() ③ printStackTrace()
* 5. 多个catch中的异常类型没有子父类关系,则谁先声明,谁后声明无所谓
* 如果多个catch中的异常类型有子父类关系,则必须将子类异常声明在父类异常之前。否则报错。
*
* 6. 在try中声明的变量,在出了try结构以后,不可被调用
* 7. try-catch-finally结构是可以嵌套使用的
#### 2. finally的使用:
* 1. finally是可选的
* 2. 将一定会被执行的代码声明在finally中。换句话说,finally中的代码一定会被执行。
* 3. 不管try中是否有仍未被处理的异常,是否try中有return,catch中是否有return,finally中的代码都一定会被执行!
* 4. 开发中,哪些代码需要声明在finally中呢?需要说动关闭的资源,比如:流资源、socket资源、数据库连接资源等,必须声明在finally中。
3.处理方式二:throws
说明:
* 异常处理的方式二:使用"throws + 异常类型",声明在方法的声明处
*
* 1. 方法内根据可能产生的异常对象的类型,在方法的声明处使用throws的方法,抛出此异常的类型即可
* 2. 使用了throws的方式处理异常,并没有根本上解决异常,只是将异常抛给方法的调用者。
* 比如:method1()将异常抛给了method2()
public class ThrowsTest {
public static void main(String[] args) {
ThrowsTest test = new ThrowsTest();
test.method3();
}
public void method3(){
try {
method2();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("可以执行的代码");
}
public void method2()throws IOException{
method1();
}
public void method1() throws FileNotFoundException,IOException{
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);//FileNotFoundException
int b = fis.read();//IOException
while(b != -1){
System.out.print((char)b);
b = fis.read();//IOException
}
fis.close();//IOException
}
- 方法的重写的要求:
* 子类重写的方法throws的异常类型A 与父类被重写的方法的异常类型B的关系为:
* 类型A可以与类型B相同,或者类型A是类型B的子类。
4. 两种方式的对比
1. 区分try-catch-finally 与 throws
* try-catch-finally:从根本上将异常的对象进行了处理。throws并没有从根本上处理异常对象。
* 2. 开发中, 如何选择异常处理的方式?
* > 如果父类被重写的方法没有声明异常类型,(即在方法声明处没有throws结构),则子类重写的方法内部如果有
* 异常需要处理的话,一定要使用try-catch-finally
* > 如果程序中有一定要被执行的代码,则考虑使用try-catch-finally。比如:资源的关闭操作
* > 如果在方法1中依次调用方法2,方法3,...此时的方法2,3..方法中如果异常的话,建议使用throws的方法
* 进行处理。在方法1中整体建议使用try-catch-finally的方式进行处理
五、手动创建异常对象并抛出:throw
/*
* 手动创建一个异常类的对象的测试:使用throw关键字
*
* 在方法内部,可以使用“throw + 异常类的对象”的方式,生成一个异常对象的同时,并将此对象抛出。
*/
public class ThrowTest {
public static void main(String[] args){
Student s = new Student();
try {
s.regist(1001);
s.regist(-1);
System.out.println(s);
} catch (Exception e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
class Student{
private int id;
public void regist(int id) throws Exception{
if(id > 0){
this.id = id;
}else{
//手动抛出一个异常类的对象
// throw new RuntimeException("输入的id非法");
throw new Exception("输入的id非法");
}
}
@Override
public String toString() {
return "Student [id=" + id + "]";
}
}
六、自定义异常类
开发中,除了可以throw一个现成的异常类的对象之外,还可以throw一个自定义异常类的对象。
/*
*
* 用户自定义异常类
*
* 要求:
* 1. 继承于现有的异常体系结构
* 2. 需要提供一个序列版本号:serialVersionUID
* 3. 提供重载的构造器
*/
public class MyException extends Exception{
static final long serialVersionUID = -70348976939L;
public MyException(){
}
public MyException(String message){
super(message);
}
}
使用:
public void regist(int id) throws MyException {
if(id > 0){
this.id = id;
}else{
//手动抛出一个异常类的对象
// throw new RuntimeException("输入的id非法");
// throw new Exception("输入的id非法");
// throw new String("输入的id非法");//编译失败
//抛出一个自定义的异常类的对象
throw new MyException("输入的id非法");
}
}