前言: java程序运行中难免会有异常出现,一些由用户造成,一些由随机因素造成,为了处理这些异常,java内置了一套遗产机制。 java中的异常是class 借鉴图片: 由图知其有两种异常: 第一种是:Error,表示严重的错误,程序对此无能无力。 第二种是:Exception,运行的错误,表示可以被捕获并处理。
我们经常使用的异常处理就是Exception Exception分为两种:
RuntimeException以及它的子类;非RuntimeException(包括IOException、ReflectiveOperationException等等)java中又分为需要捕获和不需要捕获的异常:
必须捕获的异常,包括Exception及其子类,但不包括RuntimeException及其子类,这种类型的异常称为Checked Exception。不需要捕获的异常,包括Error及其子类,RuntimeException及其子类。捕获异常使用try…catch语句,把可能发生异常的代码放到try {…}中,然后使用catch捕获对应的Exception及其子类:
public class Main { public static void main(String[] args) { byte[] bs = toGBK("中文"); System.out.println(Arrays.toString(bs)); } static byte[] toGBK(String s) { try { // 用指定编码转换String为byte[]: return s.getBytes("GBK"); } catch (UnsupportedEncodingException e) { // 如果系统不支持GBK编码,会捕获到UnsupportedEncodingException: System.out.println(e); // 打印异常信息 return s.getBytes(); // 尝试使用用默认编码 } } }可以使用多个catch语句,每个catch分别捕获对应的Exception及其子类。JVM在捕获到异常后,会从上到下匹配catch语句,匹配到某个catch后,执行catch代码块,然后不再继续匹配。 存在多个catch情况时,catch的顺序十分重要,子类需要放在前面,否则永远也匹配不到子类。
public static void main(String[] args) { try { process1(); process2(); process3(); } catch (IOException e) { System.out.println(e); } catch (NumberFormatException e) { System.out.println(e); } }无论是否捕捉到异常,都执行的语句
public static void main(String[] args) { try { process1(); process2(); process3(); } catch (UnsupportedEncodingException e) { System.out.println("Bad encoding"); } catch (IOException e) { System.out.println("IO error"); } finally { System.out.println("END"); } }finally的特点:
finally可写可不写finally总是最后执行由于某些情况下,两个异常的处理方式相同,则可以用‘|’将两个异常连接起来。
catch (IOException | NumberFormatException e) { // IOException或NumberFormatException System.out.println("Bad input");打印方法调用栈:printStackTrace()方法,在抛出异常时,能够明确的看到抛出异常最初是在哪里抛出的。
throw语句:异常正常抛出的示例
void process2(String s) { if (s==null) { throw new NullPointerException();//在这里抛出异常 } }在上述代码中,异常栈中,只是指出了很浅显的异常,并没有指出最根本的原因,如何用其找到最根本的原因。 将上述代码中process2中捕获到异常后抛出异常的部分修改为:throw new IllegalArgumentException(e); 上述代码异常栈多出了Caused by的部分,这里才是最根本的原因。
java.lang.IllegalArgumentException: java.lang.NullPointerException at Main.process1(Main.java:15) at Main.main(Main.java:5) Caused by: java.lang.NullPointerException at Main.process2(Main.java:20) at Main.process1(Main.java:13)一般来说,java给出的常用异常已经够基本开发使用,但一些大型项目中需要自定义异常,最常见的做法是自定义一个BaseException作为根异常(继承自RuntimeException),并且自定义的BaseException应该提供多个构造方法。
public class BaseException extends RuntimeException { public BaseException() { super(); } public BaseException(String message, Throwable cause) { super(message, cause); } public BaseException(String message) { super(message); } public BaseException(Throwable cause) { super(cause); } }指针在java中不存在,说法是从C语言中流传过来的,正常的说法应该是空引用。 NullPointerException是常见的错误,应早暴露早修复 避免空指针异常:应用""空字符串或空数组。 java14开始JVM可以告诉我们详细的出错信息,告诉我们Null对象是谁。