什么是Java异常?什么是异常处理?异常处理有什么优势?
一种不正常的状态,打断程序的流程,在运行时抛出的一种不正常状态。 异常处理就是一种处理运行时错误的机制。 异常处理核心优势:可以保证程序流的正常执行。
checked Exception和unchecked Exception的不同之处?
如上图所示,checked Exception就是在编译时会检查的,包括IOException 和SQLException,unchecked Exception是编译时不会检查,但是运行时会检查的。包括RunTimeException,大的划分也罢Error划分到unchecked Exception里面,但是不同的是Error无法恢复,而且Exception handle关注的也是可以处理恢复的Exception而不是不可恢复的Error。
下面给出几个unchecked Exception会发生的场景?
ArithmeticException:int a = 4/0;此时会发生ArithmeticException(算法异常),表示不符合Java运算规范。 NullPointerException :int a = null; System.out.println(a.length());当我们对一个null变量执行任何操作的时候都会出现NullPointerException(找不到指定元素)。 NumberFormatException:错误的格式化一些值的时候会出现NumberFormatException,比如:String s = “asd”; int i=Integer.parseInt(s)。想把一个String 格式化成为Integer类型是不合法的,会抛出上述错误。 ArrayIndexOutOfBoundsException:数组索引越界的异常,int a[]=new int[5]; a[10]=50;此时会抛出ArrayIndexOutOfBoundsException,这也是一个unchecked Exception,属于RunTimeException的范畴。
Exception handle有5个关键字?
try,catch, finally, throw, throws
try{}catch{}结构,try block必须跟随catch{}或者finally{}
如果异常没有被处理,那么虚拟机将会有一个默认的处理流程:打印异常描述,打印栈轨迹(也就是发生异常的方法的层次结构),最后停止程序执行。但是处理后的异常却不会干扰到正常后续程序的运行。
多个catch block对多个Exception处理的时候会发生什么?
public class TestMultipleCatchBlock{
public static void main (String args[]){
try {
int a[]=new int [5 ];
a[5 ]=30 /0 ;
}
catch (ArithmeticException e){System.out .println("task1 is completed" );}
catch (ArrayIndexOutOfBoundsException e){System.out .println("task 2 completed" );}
catch (Exception e){System.out .println("common task completed" );}
System.out .println("rest of the code..." );
}
}
rest of the code...
同一时间只有一个Exception发生,并且同一时间只有一个catch{}执行。 所有的catch{}必须有序排列,从最特殊的到最普通大众的顺序,否则会报错。
为什么我们会使用finally关键字?它的使用方法?
finally{}一般放在catch{}或者try{}后面,无论Exception是否被处理,finally{}中的内容一定会被处理,如果Exception没有被handle,Java虚拟机会在停止程序之前执行finally{}。 一般finally{}会放一些比较重要的代码,比如关闭连接,关闭文件什么的,防止由于异常造成文件的损坏或者其他一些问题。 对于每一个try{},可能有0个或者多个catch{},但是只有一个finally{} 什么时候finally{}不会执行呢?当调用System.exit()或者有个非常致命的错误导致程序直接退出的时候finally{}不会执行。
throw关键字,用法
throw用来明确的抛出异常 (一般是自定义的异常)
public class TestThrow1{
static void validate(int age){
if (age<18 )
throw new ArithmeticException("not valid" );
else
System.out .println("welcome to vote" );
}
public static void main (String args[]){
validate(13 );
System.out .println("rest of the code..." );
}
}
Exception的传播?为什么?如何传播?
一个Exception最初被抛出是在调用堆栈的top,如果它没有被catch捕获,那么它会调用堆栈下降到下一个方法,如果还没有被catch,它将继续下沉,一直沉到底部,这个叫做Exception的传播。 默认情况下,unchecked Exception在可以在传播链中传播。 默认情况下,checked Exception不可以可以传播,只能在Exception发生的地方catch
class TestExceptionPropagation1{
void m(){
int data=50 /0 ;
}
void n(){
m();
}
void p(){
try {
n();
}catch (Exception e){System.out .println("exception handled" );}
}
public static void main (String args[]){
TestExceptionPropagation1 obj=new TestExceptionPropagation1();
obj.p();
System.out .println("normal flow..." );
}
}
normal flow...
class TestExceptionPropagation2{
void m(){
throw new java.io.IOException("device error" );
}
void n(){
m();
}
void p(){
try {
n();
}catch (Exception e){System.out .println("exception handeled" );}
}
public static void main (String args[]){
TestExceptionPropagation2 obj=new TestExceptionPropagation2();
obj.p();
System.out .println("normal flow" );
}
}
Throws关键字,用在什么地方?怎么用?
throws用来declare一种异常,告诉程序这可能会出现Exception,请求Exception handle代码,但是这个只能用来处理checked Exception ,unchecked Exception和Error都不行,这是因为unchecked Exception只能在程序运行的时候才知道它是不是有问题,所以无法提前预防(取决于你的代码的正确性)。Error超出了程序的控制范围,就是说出了错,比如内存溢出或者虚拟机错误,程序也处理不了。 优势:弥补了在Exception 传播中checked Exception无法被传播的问题。
import java.io.IOException;
class Testthrows1{
void m()throws IOException{
throw new IOException("device error" );
}
void n()throws IOException{
m();
}
void p(){
try {
n();
}catch (Exception e){System.out.println("exception handled" );}
}
public static void main (String args[]){
Testthrows1 obj=new Testthrows1();
obj.p();
System.out.println("normal flow..." );
}
}
exception handled
normal flow...
Rule: If you are calling a method that declares an exception, you must either caught or declare the exception.(如果调用一个declare了Exception方法的方法,你必须catch这个Exception或者同样declare这个Exception,否则会出现错误)。
throw和throws的不同之处?
0.throw是为了抛出一个异常(就是创建一个异常),throws是声明一个异常,是为了处理可能发生的异常。 1.使用throw无法propagated checked Exception,但是throws可以。 2.throw后面跟着一个异常实例(new IOException(“Exception occured”)), throws后面跟着一个方法体。 3.throw在方法体中使用,throws在方法名的地方使用 4.throw不能同时抛出多个Exception,但是throws可以同时声明多个Exception(throws IOException,SQLException)。
finally,final, finalize三者的区别?
final是一个关键字 ,final被用来限制class,variable,method。被final修饰的class不能被继承,被final修饰的method无法被重写,被final修饰的variable无法修改。 finally是一个代码块(block),放置比较重要的代码,无论Exception是否被handle,这个block中的代码都会被执行。 finalize是一个method,用在对象被GC之前的线程清理
custome Exception(自己定义的异常)?
通过extend Exception,可以定义自己的异常,传入参数,或者错误信息。
方法重写时的异常处理?
如果superclass没有declare(throws)Exception:那么subclass重写的方法不能declare(throws)checked Exception(such as IOException,SQLException),但是能够declare(throws)unchecked Exception(RunTimeException such as ArithmeticException,NullPointerException,NameFormatException,ArrayIndexOutOfBoundsException)。 如果superclass已经declare(throws)Exception:那么subclass也可以同样declare superclass的Exception的子类或者和superclass throws的Exception相同或者没有declare(throws) Exception,但是一定记住不能声明superclass的Exception(question:如果superclass和subclass的Exception相同怎么办?是可以抛出的。IDE可以帮助我们发现这一点,所以不用担心)。 这里有比较详细的代码,如果有兴趣可以看看