Java中有一个Throwable的类,它有两个子类,一个是Error类,另一个是Exception类。对于错误而言,是很难解决的,比如内存溢出等,不能够通过异常处理来解决;异常是程序中发生的不正常事件流,比如10除以0, 文件不存在等,需要程序员关心,通过处理程序让程序继续运行下去。但是错误是无法控制的,程序肯定要中断。
异常分为运行期异常(RuntimeException)和编译期异常(CheckedException)
运行期异常:程序运行时抛出的异常,编译器不会强制处理,在运行期才会处理的异常,这是就需要程序员找到该异常,并修改。
编译期异常:出去运行期异常其他都为编译期异常,程序是正确的,但因为外界条件不满足会引发异常,此时编译器会强制要求处理这类异常。这就需要用到throw、throws、try、catch。
public class A {
public void a(int i) {
try{
System.out.println("1.");
b(i);
System.out.println("2.");
}catch(IOException e){
System.out.println("3.1");
e.printStackTrace();
}
catch(SQLException e){
System.out.println("3.2");
e.printStackTrace();
}
catch(Exception e){
System.out.println("3.3");
e.printStackTrace();
}
System.out.println("4.");
}
public void b(int i) throws IOException,SQLException{
if(i>20){
throw new SQLException("错错错");
}
if(i>5){
throw new IOException("报错");}
}
public static void main(String[] args) {
A a=new A();
a.checkedException(2);
}
}
在上述代码中我们看到了,方法b中有一个int参数i,当i大于20时,用throw抛出SQLException,i大于5时throwIOException,当你抛出了异常但是不做处理编译器就会报错,此时你可以throws给上一级,用在方法上,可以用throws一层一层的抛给上一级,但是这个异常总是要解决的,程序员也需要分析代码,在合适的地方解决这个异常,解决异常时就需要用到try和catch,try就是找到这个异常,一旦找到异常后面的代码块便不会执行,跳到catch去,catch到哪个异常就执行catch花括号里面的代码。
在Java语言异常处理机制中还有两个关键字:finally和return,简单来说finally代码块里的代码是无论如何都会执行的,且只能有一个finally。return就是返回,后面的不执行了。
比如在return中使用finally
public class MultipleReturns {
public static void f(int i){
System.out.println("Initialization that requires cleanup");
try{
System.out.println("Point 1");
if(i==1) return;
System.out.println("Point 2");
if(i==2) return;
System.out.println("Point 3");
if(i==3) return;
System.out.println("End");
return;
}
finally{
System.out.println("Performing cleanup.");
}
}
public static void main(String[] args) {
for(int i=1;i<=4;i++){
f(i);
}
}
}
无论从何处return,finally里的内容都会执行,还需要注意以下几点:
1. try-catch-finally里都没有return ,finally 之后有个return ,如果try中有异常,finally执行完后,还能执行return吗?
2. 在存在try-catch-finally的方法中,return可能出现的位置有4个,在try中,在catch中,在finally中,在finally后(try-catch-finally外的语句块)。
3.在这4个位置都出现return的情况下(事实上应该是不可能的,如果前面3个位置都存在return,那么最后一个位置的return就成了unreachable code,编译不会通过),最终会执行的return应该是finally中的return。也就是finally中的return会覆盖掉其它位置的return。