Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误。程序不应该抛出这种类型的对象。
第一类:由编程错误导致的异常——RuntimeException(运行时异常)
错误的强制类型转换数组访问越界访问null指针…
第二类:其他异常(编译时异常)——必须在编写程序时预先对这种异常进行处理
试图超越文件末尾继续读取数据试图打开一个不存在的文件试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在。…
Java将派生于Error类或者RuntimeException类的所有异常成为非检查型(unchecked)异常,所有其他的异常称为检查型(checked)异常。
1、throws关键字
在方法的名称后用throws关键字声明,将异常抛出。方法的调用者仍要对该异常进行处理,可以抛出也可以使用try/catch进行捕捉。出现异常后,程序就会终止,后面的语句无法继续执行。
2、try/catch语句
在可能会发生异常的方法处用try/catch语句将其包裹起来,try语句块中写方法的调用,catch语句块对异常进行处理。捕捉到异常后,try/catch语句块后的语句仍然可以继续执行。
如何选择
选择的依据: 是否希望调用者对异常进行处理
如果希望让调用者知道可能会发生什么样的异常,想让调用者自己来处理一下,则使用throws关键字进行异常的处理,其他情况使用try/catch。
1、getMassage()
获取异常的描述信息
public class ExceptionMethodTest(){ public static void main(String[] args){ NullPointerException e = new NullPointerException("空指针异常"); String msg = e.getMessage(); System.out.println(msg); //输出结果: // 空指针异常 } }2、printStackTrace()
打印异常追踪的堆栈信息
public class ExceptionMethodTest{ public static void main(String[] args){ NullPointerException e = new NullPointerException("空指针异常"); e.printStackTrace(); //输出结果: // java.lang.NullPointerException: 空指针异常 // at ExceptionMethodTest.main(ExceptionMethodTest.java:3) } }运行结果:
java.io.FileNotFoundException: E:\不存在的路径 (系统找不到指定的文件。) at java.base/java.io.FileInputStream.open0(Native Method) at java.base/java.io.FileInputStream.open(FileInputStream.java:212) at java.base/java.io.FileInputStream.(FileInputStream.java:154) at java.base/java.io.FileInputStream.(FileInputStream.java:109) at ExceptionMethodTest.method3(ExceptionMethodTest.java:23) at ExceptionMethodTest.method2(ExceptionMethodTest.java:19) at ExceptionMethodTest.method1(ExceptionMethodTest.java:15) at ExceptionMethodTest.main(ExceptionMethodTest.java:7)
查看打印的堆栈异常信息时,略过sun公司写好的java包中的异常语句后,从上往下一行一行检查程序出现的错误。
/* at ExceptionMethodTest.method3(ExceptionMethodTest.java:23) 表示程序的第23行出现错误并且是问题的根源 at ExceptionMethodTest.method2(ExceptionMethodTest.java:19) at ExceptionMethodTest.method1(ExceptionMethodTest.java:15) at ExceptionMethodTest.main(ExceptionMethodTest.java:7) */finally与try/catch语句一起使用,finally中的语句无论try语句块中是否出现异常都一定会执行。finally必须与try一起出现,不能单独编写。
public class FinallyTest{ public static void main(String[] args){ try{ System.out.println("try"); return; } finally { System.out.println("finally"); } } } //输出结果: // try // finally无法到达的语句:(Unreachable statement)
因为在try语句块中执行完retrun 程序就会结束,最后一行语句不会被执行。
public class FinallyTest{ public static void main(String[] args){ try{ System.out.println("try"); return; } finally { System.out.println("finally"); } System.out.println("无法到达的语句"); //编写时报错 Unreachable statement } }当显式的退出JVM时,其后面的finally语句就不会执行了。
public class FinallyTest{ public static void main(String[] args){ try{ System.out.println("try"); System.exit(0); //退出JVM }finally{ System.out.println("finally"); //不会执行 } } }final关键字修饰的类不能被继承,修饰的变量无法修改即为常量,修饰的方法为不可覆盖的方法。
finaly关键字使用在处理异常时,与try/catch一起使用。
finalize是Object类的一个方法名,由JVM的GC垃圾回收器负责调用。(已废弃)
有时在业务中异常并不能满足需求,则可以自定义异常。
自定义异常分为两步:
1、编写自定义异常类并继承Exception或者RuntimeException(取决于自定义的异常类型);
2、提供两个构造方法,一个无参,一个带有一个String参数。
//自定义异常 public class MyException extends Exception{ //无参构造方法 public MyException(){} //带有一个String参数的构造方法 public MyException(String s){ super(s); } }