java中的异常处理机制

异常是指程序运行时所发生的非正常情况或错误,java中使用异常能够降低错误处理代码的复杂度,如果不使用异常,就必须检查特定的错误,并在程序中的许多地方去处理它。

1.java的标准异常

Throwable这个java类被用来表示任何可以作为异常被抛出的类,Throwable对象可以分为两种类型,Error和Exception。

Error可以用来表示编译时和系统错误,表示程序在运行期间出现了非常严重的错误,并且该错误是不可恢复的,由于这属于JVM层次的严重错误,因此这种错误会导致程序终止执行。

Exception是可以被抛出的基本类型,表示可恢复的异常,是编译器可以捕捉到的,它包含两种类型,检查异常和运行时异常。检查异常是在程序中经常碰到的异常,比如最常见的IO异常和SQL异常,这种异常都发生在编译阶段,java编译器强制程序去捕获此类型的异常,即把可能会出现异常的代码块放在try块中,把对异常的处理放在catch块中。

运行时异常不同于检查异常,当出现这种异常时,会由JVM来处理,最常见的运行时异常包括NullPointerException(空指针异常),ClassCastException(类型转换异常),ArrayIndexOutOfBoundsException(数组越界异常),ArrayStoreException(数组存储异常),BufferOverFlowException(缓冲区溢出异常),ArithmeticException(算术异常)等。出现运行时异常后,系统会把异常一直往上层抛出,直到遇到处理代码为止,若没有处理块,则抛到最上层,如果是多线程,就用Thread.run()方法抛出,如果是单线程,就用main()方法抛出。抛出之后,如果是多线程,这个线程就退出了,如果是主线程,整个程序也就退出了。

2.抛出异常的三种方式

2.1 系统自动抛出异常

@Test
public void test1(){
  int a=8;
  int b=0;
  System.out.println(a/b);
}

运行后抛出异常:java.lang.ArithmeticException: / by zero

2.2 throw

throw是语句抛出一个错误,一般是在代码块的内部,当程序出现某种逻辑错误时由程序员主动抛出某种特定类型的异常。在使用new创建了异常对象之后,此对象的引用将传递给throw。

@Test
public void test2(){
  String s="abc";
  if(s.equals("abc")){
	throw new NumberFormatException(); 
  }else{
	System.out.println(s);
  }
}

运行后抛出异常:java.lang.NumberFormatException。

2.3 throws

当某个方法可能会抛出异常时,用throws声明可能抛出的异常,然后上交给它的方法程序处理。

public static void f() throws NumberFormatException{
  System.out.println("try语句块先执行");
  String s="abc";
  System.out.println(Double.parseDouble(s));
}
public static void main(String[] args){
  try{
    f();
  }catch(NumberFormatException e){
    System.err.println("非数据类型不能强制类型转换。");
  }
}

运行后输出:

try语句块先执行
非数据类型不能强制类型转换。

3.捕获异常

java程序在抛出异常后,首先使用new在堆上创建异常对象,然后当前的执行路径被终止,并且从当前环境中弹出对异常对象的引用,之后处理机制接管程序,并且开始寻找异常处理程序来继续执行程序。

如果在方法内部抛出异常,这个方法将在抛出异常的过程中结束,要是不希望方法就此结束,可以在方法内设置一个try块来捕获异常。抛出的异常必须在异常处理程序中得到处理,异常处理程序紧跟在try块之后,以关键字catch表示。异常处理程序的任务就是将程序从错误状态中恢复,以使程序要么换一种方式运行,要么继续运行下去。

import org.junit.Test;
class Exception1 extends Exception{
	
}
public class ExceptionTest {
  public int testFinally(){
    try{
      System.out.println("try执行");
      throw new Exception1();
    }catch(Exception1 e){
      System.out.println("catch");
      return 0;
    }finally{
      System.out.println("execute finally");
      return 1;     }   }   @Test   public void test(){ int result=testFinally(); System.out.println(result);   } }

finally块的作用是为了保证无论出现什么情况,finally块里的代码一定会执行。 如果try-finally和catch-finally中都有return,那么finally块里的return语句将会覆盖别处的return语句,最终返回到调用者那里的都是finally中return值。(其他正常执行,但是return由finally中的return覆盖。)

程序运行结果:

try执行
catch
execute finally
1

在使用异常处理时,还需注意java异常处理用到了多态的概念,如果在异常处理过程中,先捕获了基类,然后再捕获子类,那么捕获子类的代码块将永远不会被执行,因此在进行异常捕获时,正确的应该是先捕获子类,再捕获基类的异常信息。

try{
  // }catch(SQLException e1){   // }catch(Exception e2){   // }

 

posted on 2019-05-15 17:17  BlueTree2  阅读(150)  评论(0编辑  收藏  举报

导航