Java中异常处理

java.lang包里的Throwable类有两个重要的子类:Exception(异常)和Error(错误)

Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。

Exception(异常):是程序本身可以处理的异常。Exception 类有一个重要的子类 RuntimeException。RuntimeException 异常由Java虚拟机抛出。NullPointerException(要访问的变量没有引用任何对象时,抛出该异常)、ArithmeticException(算术运算异常,一个整数除以0时,抛出该异常)和 ArrayIndexOutOfBoundsException (下标越界异常)

 

Throwable类常用方法

1.public string getMessage():返回异常发生时的详细信息

2.public string toString():返回异常发生时的简要描述

3.public string getLocalizedMessage():返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可以声称本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage()返回的结果相同

4.public void printStackTrace():在控制台上打印Throwable对象封装的异常信息

 

异常处理总结

try 块:      用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。

catch 块: 用于处理try捕获到的异常。

finally 块: 无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行

 

在以下4种特殊情况下,finally块不会被执行:

1.在finally语句块第一行发生了异常。 因为在其他行,finally块还是会得到执行

2.在前面的代码中用了System.exit(int)已退出程序。 exit是带参函数 ;若该语句在异常语句之后,finally会执行

3.程序所在的线程死亡。

4.关闭CPU。

 

抛出异常:一个方法不处理这个异常,而是调用层次向上传递,谁调用这个方法,这个异常就由谁来处理

系统会自动抛出异常,比如除0这样的操作,包括空指针这样的

throw:将产生的异常抛出(强调是动作),抛出的既可以是这个异常的引用,也可以是异常对象(在方法体内)

throws:一个方法可能出现异常,但又没有能力处理这种异常,在方法声明出用throws抛出异常

 

注意 : 调用可能会抛出异常的方法,必须添加try-catch代码块尝试去捕获异常 或者 添加throws 声明 来将异常 抛出给更上一层的调用者进行处理,这里需要注意一个细节:新的异常包含原始异常的所有信息,根据这个我们可以去追溯最初异常发生的位置

 

自定义异常:

    自定义异常可以对我们需要判断的某些异常做专门的捕获。比如空指针。或者数值转换异常。等等。我们都会根据对应的异常给予用户相应的提示信息。让用户知道自己是不是做错了什么操作。还有当我们捕获到对应的异常。那我们能够根据这个异常做相关的后续操作,比如在事务中我们可以通过定义异常来回滚。

自定义的异常类:继承Exception类

public class MyException extends Exception
{
  public MyException()
  {

  }
  public MyException(String s)
  {
        super(s);
  }

}

一个可能抛出异常的方法:

public class ExceptionClass
{
  public String setNumber(int number) throws MyException
    {
        if(number >= 0 && number <=100)
        {
            return "正常";
        }
        else
        {
            throw new MyException("输入错误");
        }
    }

}

在主类中调用

public class MainClass
{
   public static void main (String args[])
    {
        try{
            ExceptionClass exception = new ExceptionClass();
            //设置0-100范围数字
            String s = exception.setNumber(90);
            System.out.println(s);
        }
        catch(MyException e)
        {
            System.out.println("异常信息为:"+e.getMessage());
        }
    }
}

会依次编译MyException.java->ExceptionClass.java->MainClass.java

利用Aop的思想定义一个统一处理异常的切面类:避免在controller方法中反复用try/catch来捕获

封装异常信息的类:

public class ExceptionInfo {

    private String className;
    private String methodName;
    private Date logTime;   //异常记录时间
    private String message;//异常信息
    //.....其他属性
    //省略set get
 }

统一处理异常的切面类:

@Aspect
public class ExceptionMonitor {

    /**
     * 定义异常监控类
     */
    @Pointcut("连接点")void exceptionMethod() {
    }

    @Around("exceptionMethod()")
    public Object monitorMethods(ProceedingJoinPoint thisJoinPoint) {
        try {
            return thisJoinPoint.proceed();
        } catch (Throwable e) {
            ExceptionInfo info=new ExceptionInfo();
            //异常类记录
            info.setClassName(thisJoinPoint.getTarget().getClass().getName());
            info.setMethodName(thisJoinPoint.getSignature().getName());
            info.setLogTime(new Date());
            info.setMessage(e.toString());
            //上传日志系统,自行完善
            //ExceptionReportUtils.report(info);
            return null;
        }
    }
}

就可以自动将接口方法中出现的异常全部保存到日志系统中

 

posted @ 2019-01-16 00:02  LeeJuly  阅读(197)  评论(0编辑  收藏  举报