java中异常有哪些,怎么使用?
我想着也是大家面试中常见的一个问题,那么这里就写写对于这个点的一些整理
先看下百度百科是怎么说的
异常:程序在运行过程中发生由于外部问题(如硬件错误、输入错误)等导致的程序异常事件。
(在Java等面向对象的编程语言中)异常本身是一个对象,产生异常就是产生了一个异常对象
异常跟错误的区别
异常都是运行时的。编译时产生的不是异常,而是错误(Error)。
需要注意的是,程序设计导致的错误(Error)不属于异常(Exception)。
异常处理体系
Throwable:是所有Errors和Exceptions的superclass
|- Error:系统内部错误,这类错误由系统进行处理,程序本身无需获取处理
|- Exception:可处理的异常
|- 非运行时异常
|- IOException
|- EOFException
|- FileNotFoundException
|- MalformedURLException
|- UnknownHostException
|- ClassNotFoundException
|- CloneNotSupported
|- RuntimeException:可以捕获的异常,也可以不捕获的异常;是those异常的超类
|- ArithmeticException
|- ClassCastException
|- IllegalArgumentException
|- IllegalStateException
|- IndexOutOfBoundsException
|- NoSuchElementException
|- NullPointerException
执行顺序:
Throwable:Throwable是整个异常的超类
public Throwable() {
fillInStackTrace();
}
public Throwable(String message) {
fillInStackTrace();
detailMessage = message;
}
public Throwable(String message, Throwable cause) {
fillInStackTrace();
detailMessage = message;
this.cause = cause;
}
public Throwable(Throwable cause) {
fillInStackTrace();
detailMessage = (cause==null ? null : cause.toString());
this.cause = cause;
}
在Throwable的构造方法中,我们可以看到的两个参数是message和cause,这两个就是异常的信息和产生异常的原因;
我们还看到fillInStackTrace这个方法: 这个方法就是在Throwable对象中填充执行堆栈信息,然后记录在当前线程的栈帧状态
private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
public synchronized Throwable fillInStackTrace() {
if (stackTrace != null ||
backtrace != null /* Out of protocol state */ ) {
fillInStackTrace(0);
stackTrace = UNASSIGNED_STACK;
}
return this;
}
private native Throwable fillInStackTrace(int dummy);
上面这个方法定义了一个数组,数组的类型是StackTraceElement。而且采用了final类型的数组,证明其不可在引用其他类型
那么ELement包含的内容就是各种信息了
public final class StackTraceElement implements java.io.Serializable {
//可以看出这是一个final class,说明他是一个基础类不许被继承。
private String declaringClass;
// 方法的类名
private String methodName;
//方法名
private String fileName;
//文件名
private int lineNumber;
// 调用的行数
// =========构造器======
public StackTraceElement(String declaringClass, String methodName,
String fileName, int lineNumber) {
this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
this.methodName = Objects.requireNonNull(methodName, "Method name is null");
this.fileName = fileName;
this.lineNumber = lineNumber;
}
回到fillInStackTrace方法,它还调用了fillInStackTrace(0) ,是由下面这个方法实现的
private native Throwable fillInStackTrace(int dummy);
**这是一个native方法,就是去底层本地方法来获取当前线程的堆栈信息。据悉这是一个非常耗时的方法。**如果我们仅仅需要用到异常的传播性质,而不关心异常的堆栈信息,那么完全可以在自定义异常类的时候重写fillInStackTrace()方法。
后续的printStackTrace就是在栈帧中输出对应的信息。
程序在运行期间出现了十分严重,不可恢复的错误
======Error======
public class Error extends Throwable {
static final long serialVersionUID = 4980196508277280342L;
public Error() {
super();
}
public Error(String message) {
super(message);
}
public Error(String message, Throwable cause) {
super(message, cause);
}
public Error(Throwable cause) {
super(cause);
}
protected Error(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Exception是应用层面上最顶层的异常类
======Exception======
public class Exception extends Throwable {
static final long serialVersionUID = -3387516993124229948L;
public Exception() {
super();
}
public Exception(String message) {
super(message);
}
public Exception(String message, Throwable cause) {
super(message, cause);
}
public Exception(Throwable cause) {
super(cause);
}
protected Exception(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
try{}catch(Exception e){}finally{}和throws两种办法。try{}catch(Exception e){}finally{}是在方法中对异常进行捕获,catch可以写多个,Java运行时系统从上到下分别对每个catch语句处理的例外类型进行检测,直到找到类型相匹配的catch语句为止。(具体的就不过多赘述)throws是出现在方法头部,个人理解算是在最外层抛出异常。
注意点: