Java Exception

Java Exception

异常的层级:

异常的层级

Checked VS Unchecked Exception

参考:

有两种异常:checked exceptions 和 unchecked exceptions。主要区别是checked exception在编译的时候检查,unchecked exception在运行时检查。

checked exception

checked exception要使用 try-catch 来捕获或者使用throws关键字来声明,否则的话,程序将会报编译错误。

如下的例子:读取myfile.txt中的内容并在屏幕上显示,这个程序有3处抛出checked exception

1.FileInputStream抛出FileNotFoundException
2.read()方法抛出IOException
3.close()方法抛出IOException

import java.io.*;
class Example {  
   public static void main(String args[]) 
   {
    FileInputStream fis = null;
    /*This constructor FileInputStream(File filename)
     * throws FileNotFoundException which is a checked
     * exception*/
        fis = new FileInputStream("B:/myfile.txt"); 
    int k; 

    /*Method read() of FileInputStream class also throws 
     * a checked exception: IOException*/
    while(( k = fis.read() ) != -1) 
    { 
        System.out.print((char)k); 
    } 

    /*The method close() closes the file input stream
     * It throws IOException*/
    fis.close();    
   }
}

会出现编译错误

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
Unhandled exception type FileNotFoundException
Unhandled exception type IOException
Unhandled exception type IOException

如何解决呢?
1.使用throws关键字声明异常

public static void main(String args[]) throws IOException, FileNotFoundException

2.使用try-catch块来捕获

import java.io.*;
class Example {  
   public static void main(String args[])
   {
    FileInputStream fis = null;
    try{
        fis = new FileInputStream("B:/myfile.txt"); 
    }catch(FileNotFoundException fnfe){
            System.out.println("The specified file is not " +
            "present at the given path");
     }
    int k; 
    try{
        while(( k = fis.read() ) != -1) 
        { 
        System.out.print((char)k); 
        } 
        fis.close(); 
    }catch(IOException ioe){
        System.out.println("I/O error occurred: "+ioe);
     }
   }
}

一些其它的Checked Exceptions

  • SQLException
  • IOException
  • DataAccessException
  • ClassNotFoundException
  • InvocationTargetException

unchecked exception

unchecked exception表示如果程序抛出了一个exception,即使你不处理异常,程序也不会报编译错误。所有的unchecked exception都是RuntimeException的子类。

如下的例子:

class Example {  
   public static void main(String args[])
   {
    int num1=10;
    int num2=0;
    /*Since I'm dividing an integer with 0
     * it should throw ArithmeticException*/
    int res=num1/num2;
    System.out.println(res);
   }
}

上述的代码,会成功的编译,但是在运行时会抛出一个ArithmeticException,表示这个异常是在运行时检查的,而不是在编译时。

常见的unchecked exception

  • NullPointerException
  • ArrayIndexOutOfBoundsException
  • ArithmeticException
  • IllegalArgumentException

try-catch

参考:

try-catch的流程:
1.如果try块中发生了异常,那么对异常的控制就转到了catch块中。
2.finally块最终都会执行

多个catch块

class Example2{
   public static void main(String args[]){
     try{
         int a[]=new int[7];
         a[4]=30/0;
         System.out.println("First print statement in try block");
     }
     catch(ArithmeticException e){
        System.out.println("Warning: ArithmeticException");
     }
     catch(ArrayIndexOutOfBoundsException e){
        System.out.println("Warning: ArrayIndexOutOfBoundsException");
     }
     catch(Exception e){
        System.out.println("Warning: Some Other exception");
     }
   System.out.println("Out of try-catch block...");
  }
}

输出结果为:

Warning: ArithmeticException
Out of try-catch block...

嵌套的try-catch

参考:

Each time a try block does not have a catch handler for a particular exception, the stack is unwound and the next try block’s catch (i.e., parent try block’s catch) handlers are inspected for a match.
If no catch block matches, then the java run-time system will handle the exception.

如下的例子:

class Nest{
   public static void main(String args[]){
     //Parent try block
     try{
        //Child try block1
         try{
            System.out.println("Inside block1");
            int b =45/0;
            System.out.println(b);
         }
         catch(ArithmeticException e1){
            System.out.println("Exception: e1");
         }
         //Child try block2
         try{
            System.out.println("Inside block2");
            int b =45/0;
            System.out.println(b);
         }
         catch(ArrayIndexOutOfBoundsException e2){
            System.out.println("Exception: e2");
         }
        System.out.println("Just other statement");
    }
    catch(ArithmeticException e3){
         System.out.println("Arithmetic Exception");
         System.out.println("Inside parent try catch block");
    }
    catch(ArrayIndexOutOfBoundsException e4){
        System.out.println("ArrayIndexOutOfBoundsException");
         System.out.println("Inside parent try catch block");
    }
    catch(Exception e5){
        System.out.println("Exception");
         System.out.println("Inside parent try catch block");
     }
     System.out.println("Next statement..");
  }
}

其输出结果为:

Inside block1
Exception: e1
Inside block2
Arithmetic Exception
Inside parent try catch block
Next statement..

要点是:无论何时,如果子try-catch不能处理异常,那么控制器就会回到父级的try-catch,如果父级也不能处理,程序就会挂掉。

再看如下的例子:

class NestingDemo{
   public static void main(String args[]){
      //main try-block
      try{
        //try-block2
        try{     
            //try-block3
            try{
                int arr[]= {1,2,3,4};
                /* I'm trying to display the value of
                 * an element which doesn't exist. The
                 * code should throw an exception
                 */
                System.out.println(arr[10]);
            }catch(ArithmeticException e){
                System.out.print("Arithmetic Exception");
                System.out.println(" handled in try-block3");
            }
        }
        catch(ArithmeticException e){
           System.out.print("Arithmetic Exception");
           System.out.println(" handled in try-block2");
        }
    }
    catch(ArithmeticException e3){
        System.out.print("Arithmetic Exception");
        System.out.println(" handled in main try-block");
    }
    catch(ArrayIndexOutOfBoundsException e4){
        System.out.print("ArrayIndexOutOfBoundsException");
        System.out.println(" handled in main try-block");
    }
    catch(Exception e5){
        System.out.print("Exception");
        System.out.println(" handled in main try-block");
     }
  }
}

其输出结果为:

ArrayIndexOutOfBoundsException handled in main try-block

ArrayIndexOutOfBoundsException出现在try-block3中,由于block3没有处理这个异常,那么就交由try-block2try-block2也没有处理这个异常,就交给父try-block 来处理。

用户自定义异常

参考:

使用throw关键字抛出user-defined 的异常。
例子 1: How to throw your own exception explicitly using throw keyword

package beginnersbook.com;
class MyOwnException extends Exception {
   public MyOwnException(String msg){
      super(msg);
   }
}

class EmployeeTest {
   static void  employeeAge(int age) throws MyOwnException{
      if(age < 0)
         throw new MyOwnException("Age can't be less than zero");
      else
         System.out.println("Input is valid!!");
   }
   public static void main(String[] args) {
       try {
            employeeAge(-2);
       }
       catch (MyOwnException e) {
            e.printStackTrace();
       }
   }
}

输出结果为:

beginnersbook.com.MyOwnException: Age can't be less than zero

例子2: How to throw an already defined exception using throw keyword

package beginnersbook.com;
class Exception2{
   static int sum(int num1, int num2){
      if (num1 == 0)
         throw new ArithmeticException("First parameter is not valid");
      else
         System.out.println("Both parameters are correct!!");
      return num1+num2;
   }
   public static void main(String args[]){
      int res=sum(0,12);
      System.out.println(res);
      System.out.println("Continue Next statements");
   }
}

输出结果为:

Exception in thread main java.lang.ArithmeticException: First parameter is not valid

finally return

参考:

如果在try-catchreturnfinally块还会执行吗?
答案是yes,finally块每次都会执行。唯一的例外是System.exit()

class FinallyDemo
{
   public static int myMethod()
   {
       try {
            //try block
            return 0;
       }
       finally {
            //finally
            System.out.println("Inside Finally block");
       }
  }
  public static void main(String args[])
  {
       System.out.println(FinallyDemo.myMethod());
  }
}

输出结果为:

Inside Finally block
0

finally块会覆写try-catch块中返回的结果吗?
会,如下例子:

public static int myTestingFuncn(){
  try{
     ....
     return 5;
  } finally {
     ....
     return 19;
   }
}

返回值为19

其它

1. java.lang.RuntimeException与java.lang.Exception的区别

RuntimeExceptions可以通过程序来避免,例如NullPointerExceptionArrayIndexOutOfBoundException。在调用方法之前检查null ,则NullPointerException就绝不会发生。

参考difference between java.lang.RuntimeException and java.lang.Exception

//Create your own exception class subclassing from Exception
class MyException extends Exception {
    public MyException(final String message) {
        super(message);
    }
}

public class Process {
    public void execute() {
        throw new RuntimeException("Runtime");
    }  
    public void process() throws MyException {
        throw new MyException("Checked");
    }
}

2.在catch中return

参考java 异常捕捉 ( try catch finally ) 你真的掌握了吗?

抛出 Exception,当 catch 体里有 return,finally 体的代码块将在 catch 执行 return 之前被执行

参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值