java中的异常不是语法错误,异常是一个对象,异常类由jdk提供,异常表示中断了正常指令流的事件。
class Teste{
public static void main(String args[]){
System.out.println(1);
int i=1/0;
System.out.println(2);
}
}
在编译时不发生报错,但在执行时发生了报错,ArthmeticException,这种异常属于UncheckException,在执行时出现异常后,就中断了正常执行的过程,后面的程序不再执行,即只打印了1,未打印2。异常类有个最基本的父类Throwable,Throwable有两个子类分为异常Exception和错误Error,一旦产生Error,java虚拟机直接退出运行,Exception分为运行时异常UncheckException(RuntimeException及其子类)和编译时异常CheckException(Exception的直接子类)。
class Teste{
public static void main(String args[]){
Thread.sleep(1000);
}
}
Thread.sleep(1000);
}
}
在编译时即发生报错,InterruptedException,这种异常属于CheckException,要求进行捕获或声明,捕获的方法是采用try,catch,finally结构处理,将可能出现异常的代码放在try结构内,将对异常处理的代码放在catch结构内,finally结构通常做一些清理工作以释放资源,例如关闭异常发生前打开的文件,finally结构无论是否出现异常都会执行,try结构在发生异常时跳到catch结构,不发生异常则不执行catch结构。UncheckException由于编译不发生报错,要进行try,catch,finally处理,以在编译时显抛出异常,下面对上述UncheckaException的代码进行try,catch,finnally处理。
class Teste{
public static void main(String args[]){
System.out.println(1);
try{
System.out.println(2);
int i=1/0;
System.out.println(3);
}
catch(Exception e){
System.out.println(4);
e.printStackTrace();
System.out.println(5);
}
finally{
System.out.println(6);
}
System.out.println(7);
}
}
由运行结果可知,在发生异常时,由发生异常部分的代码(try结构中输出3上一行代码),直接跳到catch结构中,使用catch中的
e.printStackTrace()函数将异常抛出,而修改int i=1/1;使其不发生异常的测试结果如下。
正常运行时,不执行catch结构中的语句,并且不论发生异常与否,都执行finally结构中的语句。
另一种异常的处理方法是对异常进行声明,对于一些编译和执行都能通过,但实际逻辑上出现问题的异常可以使用异常类声明对象然后采用throw语句进行抛出,在执行语句时,会在throw语句处终止程序,下面举一个例子。
class User {
private int age;
public void setAge(int age){
this.age=age;
System.out.println(age);
}
}
class Teste{
public static void main(String args[]){
User u=new User();
u.setAge(-20);
}
}
可以看到,输出结果为设置年龄为-20,这属于逻辑错误,但是在编译和执行过程中都不会出错,需要在定义setAge()时用异常类声明一个类对象,在年龄判断出错后将其抛出,若采用的异常类为RuntimeException这种UncheckException进行声明,则编译Teste时不会产生错误,若采用Exception这种CheckException进行声明,编译Teste时会发生错误,需要在测试语句中调用setAge()时用try,catch结构进行处理。
class User{
private int age;
public void setAge(int age){
if(age<0){
RuntimeException r=new RuntimeException("年龄不能为负数");
throw r;
}
this.age=age;
System.out.println("设置年龄为 "+age);
}
}
使用RuntimeException声明对象,在编译Teste时不会发生错误,但在执行时会报错,并终止运行,采用Exception声明对象,在编译时就会发生错误提醒,运行结果如下,
此时需要进行捕获或声明,捕获的方法是在在Teste中使用try,catch结构对setAge()进行处理。对异常进行声明需用thorws语句,在有可能产生异常对象的函数后加上thorws 异常类名,这里在User类中的函数定义public void setAge(int age)后加上throws Exception, 产生异常后不由函数处理,而在调用函数处处理。
class User{
private int age;
public void setAge(int age) throws Exception{
if(age<0){
Exception e =new Exception("年龄不能为负数");
throw e;
}
this.age=age;
System.out.println("设置年龄为 "+age);
}
}
此时对User.java进行编译时不会报错,但对Teste.java进行编译时会报错,因为在Teste中调用了产生异常对象的函数setAge()。
由于Exception类属于CheckException,导致了Teste编译的报错,采用try,catch处理异常后的代码和编译结果如下。
class Teste{
public static void main(String args[]){
User u=new User();
try{
u.setAge(-20);}
catch(Exception e){
System.out.println(e);
}
}
}
此时在编译Teste.java时不会报错,并且在执行时捕获到了异常类Exception。
综上,在一个函数有可能会产生CheckException时,可以采用在函数内使用try ,catch结构进行处理的方法,也可以在定义函数时,用throws声明异常类,并在调用函数的地方用try,catch进行处理,在一个函数可能会产生UncheckException时,用throw将异常类产生的对象抛出。