Java 异常处理:异常的概述、处理异常问题、throws和throw的区别、final,finally和finalize的区别、finally之前return、如何使用异常处理

异常的概述

异常就是出程序运行时出现的一些错误。
所有的异常类是从 java.lang.Exception 类继承的子类。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error(error一般是严重的,我们无法解决的错误,如服务器宕机) 。
异常类有两个主要的子类:IOException 类和 RuntimeException 类。
在这里插入图片描述

JVM的默认异常处理

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

自己处理异常问题

异常处理的两种方式:

  1. try…catch…finally
    try检测异常,catch捕获异常,finally释放资源(如IO流,finally是一定会执行的,就算在finally之前有return语句finally也会在return之前执行,除非System.exit(0);结束虚拟机)
try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}catch(Exception e)
{
   //处理所有异常用Exception,父类引用指向子类对象
}finally{
  // 程序代码
}

JDK1.7版本加了一个新用法:

try
{
   // 程序代码
}catch(ExceptionName1 | ExceptionName2 e)
{
   //Catch 块,这两个异常必须是不相关的异常,不能是子父类异常
}
  1. throw
    如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。

也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。

下面方法的声明抛出一个 RemoteException 异常:

import java.io.*;
public class className
{
  public void deposit(double amount) throws RemoteException
  {
    // Method implementation
    throw new RemoteException();
  }
  //Remainder of class definition
}

一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。

例如,下面的方法声明抛出 RemoteException 和 InsufficientFundsException:

import java.io.*;
public class className
{
   public void withdraw(double amount) throws RemoteException,
                              InsufficientFundsException
   {
       // Method implementation
   }
   //Remainder of class definition
}

throws如果抛出的是运行时异常RuntimeException,调用这方法可以不处理,抛和不抛效果一样,比如下面的例子,ArithmeticException是运行时异常,调用时不处理抛出异常编译时不会报错,throws ArithmeticException这个加不加运行结果都一样。

public static void main(String [] args){
    Test a = new Test();
    int x = a.div(1,0);
    System.out.println();
}

private static class Test{
    public int div(int a,int b) throws ArithmeticException{
        return a/b;
    }
}

运行结果(加不加throws ArithmeticException都一样):在这里插入图片描述
但如果throws抛出的是运行时异常以外的异常,调用这个方法时必须处理,否则编译时会报错。例如throws Exception,处理可以用同时抛出,也可以用try…catch:

同时抛出:

public static void main(String [] args)throws Exception{
    Test a = new Test();
    int x = a.div(1,0);
    System.out.println();
}

private static class Test{
    public int div(int a,int b) throws Exception{
        return a/b;
    }
}

try……catch:

public static void main(String [] args){
    Test a = new Test();
    try{
        int x = a.div(1,0);
    }catch (Exception e){
        e.printStackTrace();
    }
    System.out.println();
}

private static class Test{
    public int div(int a,int b) throws Exception{
        return a/b;
    }
}

常见运行时异常

运行时异常就是编译通过,运行时抛出的异常。
常见:

  • IndexOutOfBoundsException索引越界异常
  • NoSuchElementException被各种访问器方法抛出,表示被请求的元素不存在
  • NullPointerException空指针异常
  • ClassCastException类型转换异常
  • ConcurrentModificationException并发修改异常

常见方法:

  • getMessage ,获取异常信息。
  • toString ,错误类名+异常信息
  • JVM默认处理异常的方法:printStackTrace , 错误类名+异常信息+错误位置(行号)

throws和throw的区别

throws用在方法声明后面,跟的是异常名,可以跟多个异常名,用逗号隔开表示。抛出异常,由该方法的调用者来处理

throw用在方法体内,跟的是异常对象名,只能抛出一个异常对象名表示。抛出异常,由方法体内的语句处理

final,finally和finalize的区别

final可以修饰类,方法,变量(常量),修饰类时不能被继承,修饰方法时不能被重写,修饰变量时不能被改变,修饰引用类型变量时地址值不能改变,可以改变属性值,修饰基本数据类型时不能改变值。
finally写在try catch语句用于释放资源(关闭数据库,关闭流)
finalize()是一个方法,在垃圾回收的时候调用

finally之前return

return建立了返回路径,把要返回的值装在箱子里了,然后执行finally,虽然在finally中改变了要返回的那个变量,但是要返回路径里的值没有被改变。

异常注意事项

子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。
如果父类抛出了多个异常,子类重写父类时,只能抛出相同的类或者是他的子集,子类不能抛出父类没有的异常
如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

如何使用异常处理

原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这是用throws
区别:后续程序需要继续运行就try后续程序不需要继续运行就throws
如果JDK没有提供对应的异常,需要自定义异常.

猜你喜欢

转载自blog.csdn.net/weixin_43580841/article/details/107716531