摘要:java异样指在程序运行时可能呈现的一些谬误,如:文件找不到、网络连接失败、非法参数等。异样是一个事件,它产生在程序运行期间,中断了正在执行的程序的失常指令流。
本文分享自华为云社区《Java知识点问题精选之异样机制》,原文作者:breakDraw 。
java异样指在程序运行时可能呈现的一些谬误,如:文件找不到、网络连接失败、非法参数等。异样是一个事件,它产生在程序运行期间,中断了正在执行的程序的失常指令流。
Java通过API中Throwable类的泛滥子类形容各种不同的异样。因此,Java异样都是对象,是Throwable子类的实例,形容了呈现在一段编码中的谬误条件。当条件生成时,谬误将引发异样。对于运行时异样、谬误或可查异样,Java技术所要求的异样解决形式有所不同。
异样体系分类
Q: Throwable 和 Error的关系
A: Throwable是Error(谬误)的基类,也是Exception的基类
1个好图,可看到常见的异样和error
Q: Error和Exception的关系
A:
- Error个别是会间接引起jvm出错的谬误,例如Java虚拟机运行谬误等,如果呈现了以后线程会无奈持续运行。
- Excpetion是程序自身能够解决的异样。产生后还能失常运行。
Q: Error能够被catch捕获吗?
A: 只有是Throwable和其子类都是能够throw和catch的。 然而不倡议捕获Error。
异样体系还能够分为这2类:
- unchecked exception(非查看异样)
也称运行时异样(RuntimeException),比方常见的NullPointerException、IndexOutOfBoundsException。对于运行时异样,java编译器不要求必须进行异样捕捉解决或者抛出申明,由程序员自行决定。 - checked exception(查看异样,编译异样)
也称非运行时异样(运行时异样以外的异样就是非运行时异样),java编译器强制程序员必须进行捕捉解决,比方常见的IOExeption和SQLException。对于非运行时异样如果不进行捕捉或者抛出申明解决,编译都不会通过。
异样捕获和返回
Q: return-finally陷阱1: finally能通过批改变量,来更新return的变量值吗
int f() { int a = 1; try { return a; } finally { a=2; }}
A: 不能, f返回1。
Q: return-finally陷阱2: finally里也return时,返回哪个?
int f() { try { return 1; } finally { return 2; }}
A:返回finally里的,返回2。
Q: 什么状况下finally块里的步骤能够不执行?
A: 只有在finally之前调用System.exit(0)退出jvm, 能力让finally不执行。
Q: 上面会产生什么?
try { start();} catch (Exception ex) { System.out.println("catch Exception");} catch (RuntimeException re) { System.out.println("catch RuntimeException");}
A: 间接编译就谬误了。 catch是会按程序的且匹配1个就不再往下匹配,编译器因而辨认出RuntimeExcpetion永远不会被捕捉到,便提前报错。
Q:throw异样的时候,在finally中做return,那么异样还会抛出吗?
static int f() { try { int a = 1/0; return a; } catch (Exception e) { throw new RuntimeException(e); } finally { return -1; }}public static void main(String[] args) { System.out.println(f());}
A:不会,返回-1.
即finaly中做return会中断throw
因而永远不要在finally中去做return操作
受检异样相干问题
Q: 子类覆写基类办法时 , 能throws基类办法中不存在的异样吗?
像上面这样:
class A{ void f() throws IOException{ }}class B extends A{ void f() throws IOException, SQLException { }}
A: 不行,间接编译报错。 即子类覆写父类办法时, throws关键字前面跟的异样必须是小于等于父类办法异样的。
Q: finally中调用某资源的close时,也会抛出受检异样, 除了在finally里做try-catch,还能怎么做?
像上面这样,finally又有catch,就很难看:
TryWithResource tryWithResource = new TryWithResource(); try { System.out.println(tryWithResource.age); } catch (Exception e) { e.printStackTrace(); }finally { try { tryWithResource.close(); } catch (Exception e) { e.printStackTrace(); } }
A:如果是JDK1.7,能够用try-with-resource语法。
须要资源类实现AutoCloseable接口, 并在try的时候在try括号前面跟上资源的创立,如下:
public static void main(String[] args) { try (TryWithResource tryWithResource = new TryWithResource()) { System.out.println(tryWithResource.age); } catch (Exception e) { e.printStackTrace(); } }
这样就不须要写finally,finally+close会通过编译器给咱们主动加上。
Q: 线程抛出异样的话该怎么捕获?
A: 实现异样解决接口MyUnchecckedExceptionhandler
public class MyUnchecckedExceptionhandler implements UncaughtExceptionHandler { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("捕捉异样解决办法:" + e); }}
而后把实现类设置给对应线程。
Thread t = new Thread(new ExceptionThread());t.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());t.start();
点击关注,第一工夫理解华为云陈腐技术~