赞
踩
异常分类
Throwable共有两个子类:
Error:严重错误,无法处理。如内存溢出,系统崩溃。
Exception:异常,可进行处理分为两种
运行时异常:都是RuntimeException
类及其子类异常,如NullPointerException
(空指针异常)、IndexOutOfBoundsException
(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch
语句捕获它,也没有用throws
子句声明抛出它,也会编译通过。
非运行时异常(编译异常):是RuntimeException
以外的异常,类型上都属于Exception
类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如日期格式化异常,IOException
、SQLException
等以及用户自定义的Exception
异常,一般情况下不自定义检查异常。
package com.company;public class MyException1 { public static void main(String[] args) { int[] a = {0, 1, 2}; int doing = ArrayTools.doing(a, 3); System.out.println(doing); }}class ArrayTools { public static int doing(int[] arr, int i) { return arr[i]; }
}
try:该代码块中编写可能产生异常的代码。
catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。
finally:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。
示例代码:
public class MyException2 { public static void main(String[] args) { try{ int a=1/0; }catch (ArithmeticException e){ System.out.println(e.toString()); }finally { System.out.println("bye-bye"); } }}
输出:
java.lang.ArithmeticException: / by zerobye-bye
如何获取异常信息:
Throwable类中定义了一些查看方法:
public String getMessage()
:获取异常的描述信息,原因(提示给用户的时候,就提示错误原因。
public String toString()
:获取异常的类型和异常描述信息(不用)。
public void printStackTrace()
:打印异常的跟踪栈信息并输出到控制台。
注:当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,否则finally永远会执行。
示例代码:
public class MyException2 { public static void main(String[] args) { int a = -10; if (a < 0) { throw new ArithmeticException("a不能小于0"); } else { System.out.println(a); } }}
输出:
Exception in thread "main" java.lang.ArithmeticException: a不能小于0at com.company.MyException2.main(MyException2.java:9)
如果a<0则抛出异常,否则打印a
声明异常:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理(稍后讲解该方式),那么必须通过throws进行声明,让调用者去处理。
关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).
声明异常格式:
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
声明异常的代码演示:
public class MyException2 { public static void main(String[] args) { String s = "file1.txt"; try { demo1(s); } catch (IOException e) { e.printStackTrace(); } } private static void demo1(String a) throws IOException { if (!"file.txt".equals(a)) { throw new IOException("文件不存在"); } else { System.out.println(a); } }}
输出:
java.io.IOException: 文件不存在at com.company.MyException2.demo1(MyException2.java:17)at com.company.MyException2.main(MyException2.java:9)
注:
运行时异常被抛出可以不处理。即不捕获也不声明抛出。
如果finally有return语句,永远返回finally中的结果,避免该情况.
如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
多个异常使用捕获又该如何处理呢?
一般我们是使用一次捕获多次处理方式,格式如下:
try{ 编写可能会出现异常的代码}catch(异常类型A e){ 当try中出现A类型异常,就用该catch来捕获. 处理异常的代码 //记录日志/打印异常信息/继续抛出异常}catch(异常类型B e){ 当try中出现B类型异常,就用该catch来捕获. 处理异常的代码 //记录日志/打印异常信息/继续抛出异常}
注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。
多个异常分别处理。
多个异常一次捕获,多次处理。
多个异常一次捕获一次处理。
实际开发中也会出现很多异常,这些异常很可能在JDK中没有定义过,这时需要我们自己去定义。
异常类如何定义:
自定义编译期异常:自定义类继承于java.lang.Exception
。
自定义运行时异常:自定义类继承于java.lang.RuntimeException
。
Student:
public class Student { private String sex; public void setSex(String sex) throws Exception { if ("男".equals(sex) || "女".equals(sex)) { this.sex = sex; } else { throw new GendorException("性别必须是男或者女"); } }}
Test:
public class Test { public static void main(String[] args) { Student p = new Student(); try { p.setSex("不知道"); } catch (Exception e) { System.out.println("设置性别出错了"); e.printStackTrace();//输出异常信息 } }}
GendorException:
public class GendorException extends Exception { public GendorException(String msg) { super(msg); }}
输出:
设置性别出错了com.company.GendorException: 性别必须是男或者女at com.company.Student.setSex(Student.java:17)at com.company.Test.main(Test.java:9)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。