Java异常处理:

Java的异常处理机制可以让程序具有良好的容错性 让程序更加健壮。当出现意外的时候,Java会自动生成一个Exception对象来通知程序 从而将 实现代码 和 错误代码分离,提供更好的可读性。

1. 分类:Java中把所有非正常情况分为两种:异常(Exception) 和 错误(Error),他们都继承Throwable父类。(可通过查看API学习)
  • 分类
  • 错误(Error):一般无法恢复或不可能捕获,通常应用程序无法处理这些错误。(一般指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接接受失败等。)
  • 异常(Exception):
  • 编译期异常:不属于所有的RuntimeException类及其子类的实例。(必须显示处理)
  • 运行期异常:所有的RuntimeException类及其子类的实例。(无需显示处理)
2. Java中JVM的默认处理异常机制:

当Java代码中当出现意外时,main函数收到这个问题时,有两种处理方式:

  • 方式一: 自己将该问题处理,然后继续运行。
  • 方式二:自己没有针对的处理方式,只有交给调用main的jvm来处理,其中JVM有一个默认的异常处理机制,就将该异常进行处理,并将该异常的名称,异常的信息.异常出现的位置打印在了控制台上,同时将程序停止运行。

处理结果:展示异常,结束运行。

3. 常见处理方式和语法:

捕获异常:try …catch 和 抛出异常:throws。

try…catch处理异常的基本格式:
try	{
        可能出现问题的代码 ;
        }catch(异常名 变量名){
        针对问题的处理 ;
        }finally{
        释放资源;
        }
多异常捕获:
try {
		可能出现问题的代码 ;
 		}catch(异常名1 | 异常名2 | ....   变量名){
 			对异常的处理方案 ;
  		 }finally{
        释放资源;
        }
  • 注意
  • try中的代码越少越好,把有问题的语句放在try块里。
  • catch中要做处理,哪怕是一条输出语句也可以。(不能空处理,不能将异常信息隐藏)
  • 通常情况下,如果try块被执行一次,try块后只有一个catch块会被执行,绝不可能有多个catch块被执行。除非在循环中使用continue语句。
  • 尽量明确异常类型,不要直接用Exception异常。
  • 父类异常必须在子类异常的后面,否则JVM会直接捕获父类异常而忽略子类异常。
  • 多异常捕获的时候,这些异常之间必须是平级关系。
为什么通常情况下,如果try块被执行一次,try块后只有一个catch块会被执行?

原理解释:
当程序进入负责异常处理的catch块时,系统生成的异常对象ex将会传给catch块后的异常形参,从而允许catch块通过该对象来获取异常的详细信息。
try块后面不同的catch块提供不同的异常处理方式。
当系统发生不同情况的意外,系统会生成不同的异常,Java运行时,就根据该异常对象所属的异常类来决定使用哪个catch块来处理异常。

Java和go异常 java 异常和错误_java

4.异常处理Throwable常用方法:

方法

功能

getMessage():

获取异常信息,返回字符串

toString():

获取异常类名和异常信息,返回字符串

printStackTrace():

获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void

5.关键字:throws
  • 前提:定义功能方法时,需要把出现的问题暴露出来让调用者去处理。
  • 用法:在本方法中出现异常,若在本方法中不想处理可以在本方法签名后面使用throws+异常类进行抛出。
  • 编译器异常调用者必须显示处理。
  • 运行期异常调用者可以不处理。
  • throws可以连续抛出多个异常。
6.关键字:throw
  • 前提:在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
  • 用法:用在方法体内,后跟异常对象名,只能抛出一个异常对象名。
  • 表示抛出异常,由方法体内的语句处理。
  • throw抛出了异常,执行throw则一定是抛出了某种异常。
  • 如何处理:
  • 如果功能内部可以将异常处理 就用try。。catch处理。
  • 如果处理不了就用throws抛出,让调用者处理该异常。

throws和throw的区别:

  • throws
  • 用在方法声明后面,跟的是异常类名
  • 可以跟多个异常类名,用逗号隔开
  • 表示抛出异常,由该方法的调用者来处理
  • throws表示出现异常的一种可能性,并不一定会发生这些异常
  • throw
  • 用在方法体内,跟的是异常对象名
  • 只能抛出一个异常对象名
  • 这个异常对象可以是编译期异常对象,可以是运行期异常对象。表示抛出异常,由方法体内的语句处理
  • throw则是抛出了异常,执行throw则一定抛出了某种异常
7.关键字:finally
  • finally的特点:
  • 被finally控制的语句体一定会执行(前提 JVM没有停止)。
  • 特殊情况:在执行到finally之前JVM退出了(比如System.exit(0))
  • finally的作用:
    - 用于释放资源。
try	{
        可能出现问题的代码 ;
        }catch(异常名 变量名){
        针对问题的处理 ;
        }finally{
        释放资源;
        }
思考题:如果catch里面有return语句或者exit(0)语句,请问finally的代码将会怎么执行?
解答:

①当catch块里有exit()时,程序将不再执行final块的内容。
②当catch快里有return语句时,final语句将在return语句前面一步执行,再去执行catch块的return语句。
③当final和catch块里都有return语句时候,会执行final块的return语句。不会再去执行catch块的return语句。只能执行一条return语句。

final,finally和finalize的区别
  • final: 是一个状态修饰符, 可以用来修饰类 , 变量 , 成员方法。
  • 被修饰的类不能被子类继承, 修饰的变量其实是一个常量不能被再次赋值。
  • 被修饰的类不能被子类继承, 修饰的变量其实是一个常量不能被再次赋值。
  • 修饰的方法不能被子类重写。
  • finally:用在try…catch…语句中 , 作用: 释放资源 . 特点: 始终被执行(JVM不能退出)。
  • finalize: Obejct类中的一个方法,用来回收垃圾。
8. 自定义异常:

自定义异常概述:
因为在以后的开发过程中,我们可能会遇到各种问题,而JDK不可能针对每一种问题都给出具体的异常类与之对应。为了满足需求,我们就需要自定义异常。

  • 异常注意事项(针对编译期异常):
  • 子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类,或者子类不抛出异常也是可以的。
  • 如果父类的方法没有抛出过异常,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能捕获try,不能throws。

自定义异常:

public class Myexception extends Exception{
    public Myexception(String s) {
        super(s);
    }
}

自定义异常应用实例:

public class Test1 {
    public static void main(String[] args) throws Myexception {
        System.out.println("请输入考试成绩:");
        Scanner sc = new Scanner(System.in);
        int grade = sc.nextInt();
        if(grade>100 || grade<0){
            throw new Myexception("成绩录入有问题!");

        }else {
            System.out.println("成绩录入合格!");
            System.out.println(grade);
        }
    }
}