22. 异常(Eception)

Posted 江小白谢

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了22. 异常(Eception)相关的知识,希望对你有一定的参考价值。

1. 现实生活的病

现实生活中万物在发展和变化会出现各种各样不正常的现象。

1)例如:人的成长过程中会生病。

|——病

  |——不可治愈(癌症晚期)

  |——可治愈

    |——小病自行解决(上火,牙痛)

    |——去医院(感冒,发烧)

 

同时我们的java也可以诊断和处理这些异常

注意:

  除了RunntimeException和它的子类以外,其他的都是编译时异常,我们可以在api文档中查找,并不需要死记硬背

 

2. java异常体系图

  

|——Throwable  (实现类描述java的错误和异常)

  |——Error (错误)一般不通过代码去处理。

  |——Exceprion (异常)

    |——RuntimeException (运行时异常)jvm不强制要求进行处理

    |——编译时异常 jvm强制要求进行处理

 

1)苦恼1:为什么Error错误一般不需要代码去处理呢?

  因为有些错误程序员是很难避免的,例如内存溢出,jvm默认管理的内存为64G如果超出这个范围就会报错

//定义一个1G内存的数组
        byte[] buf = new byte[2014*2014*2014];
        System.out.println(buf);

报错:

 

 

错误(Error):

  它指的是一个合理的应用程序不能截获的严重的问题。大多数都是反常的情况。错误是JVM的一个故障(虽然它可以是任何系统级的服务)。

所以,错误是很难处理的,一般的开发人员是无法处理这些错误的。比如内存溢出.

 

2)苦恼2:为什么编译时异常jvm强制要求处理,而运行时异常jvm不强制要求处理呢?

  因为运行时异常可以通过程序员良好的编程习惯而避免,程序员可以直接找到问题代码进行处理,防止这种情况发生

例如:

  当我们执行除法运算的时候我们只需要在方法里面加一个if判断(被除数不能为0),就可以避免被除数为0的情况

  而不需要抛出处理或者try...catch

 

注意:

  a.运行时异常编译器不会检查程序员是否处理该异常,所以我们应该尽量避免这种异常的出现

 

 

3.自行处理(try...catch)

  1)单个异常处理

    例如:

class Demo2
{
    public static void main(String[] args)
    {
        div(4,0);
    }

    public static void div(int a , int b){
    
        try{
            
            System.out.println(a/b);//可能出现的异常
        
        }catch(ArithmeticException e){//异常匹配
        
            e.printStackTrace();
            System.out.println("除数不能为0");
        }
        System.out.println("运算除法");
    }
}

 


    注意:

      a.如果不用处理异常,在程序运行到病态代码时,后面的代码不会执行。如果处理了,后面的代码会正常执行

      b.如果我们需要一次处理多个异常我们需要在后面多添加几个catch语句

 

  2)多个异常处理

    例如:

class Demo2
{
    public static void main(String[] args)
    {
        int[] arr = { 1, 2 };
        arr = null;
        div(4,0,arr);
    }

    public static void div(int a , int b, int[] arr){
    
        try{
            System.out.println(arr[1]);//会报空指针异常
            System.out.println(a/b); //运算异常
            
        
        }catch(ArithmeticException e){//异常匹配
        
            e.printStackTrace();
            System.out.println("除数不能为0");
        }catch(NullPointerException  e){
            e.printStackTrace();
            System.out.println("数组为空");
        }
        System.out.println("运算除法");
    }
}

 



  注意:

    a.try中多个异常同时出现,只会处理第一条出现异常的语句,剩余的异常不再处理。

  苦恼:如果是这样,难道我要记住所有的预定义异常吗?

    其实我们可以用多态的方式来捕获异常,进行处理

  
  例如: 

class Demo2
{
    public static void main(String[] args)
    {
        div(4,0);
    }

    public static void div(int a , int b){
    
        try{
            System.out.println(a/b); //运算异常
            
        }catch(Exception e){//异常匹配
            e.printStackTrace();
            System.out.println("除数不能为0");
        
        }
    }
}

 



 

  注意:

    因为Exception是所有异常的父类所以无论try语句块中出现何种错误,都会进行处理,这样导致的是,我们没办法对特定异常进行特定的处理。

    所以我们一般在catch(Exception e)前捕获一些我们知道可能要出现异常的代码,而把catch(Exception e)写在后面防止我们不知道的异常发生

 

3.抛出异常(throw throws)

  1)语法

      throws 异常名     声明异常

      throw new 异常名    抛出异常

 

  2)代码:

class Demo2
{
    public static void main(String[] args)
    {
        try{
            div(4,0);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void div(int a , int b) throws Exception{
    
        if(b == 0){
            throw new Exception("除数为0");
        }
    }
}

 


   注意:

      a.如果调用抛出异常的方法时,调用者必须处理异常或者抛出代码.

   

  苦恼:main方法抛出异常谁去处理呢?

     

  因为程序运行时jvm会调用main方法,所以如果main方法抛出异常jvm会自动处理

  代码:

public static void main(String[] args) throws Exception
{
   div(4,0);
}

 



  在实际的开发中预定义的异常并不能帮我们解决所有问题,这时我们就需要自定义异常了

 

4.自定义异常

  实例代码:

 

/*

    需求:模拟自己去吃木桶饭,如果没有带够10块,就抛出异常
    带够就吃木桶饭

    Exception的构造方法:
        
        1. Exception()     构造详细消息为 null 的新异常。

        2. Exception(String message) 构造带指定详细消息的新异常。
          
        3. Exception(String message, Throwable cause)  构造带指定详细消息和原因的新异常。
          
        4. Exception(Throwable cause)
            
            根据指定的原因和 (cause==null ? null : cause.toString()) 的详细消息构造新异常(它通常包含 cause 的类和详细消息)。

*/


class MoneyException extends Exception{

    public MoneyException(String message){

        //调用Exception一个参数的构造方法
        super(message);
    }
}


class  Demo1{
    
    public static void main(String[] args) {
        int money = 5;
        try{
        
            eat(money);
        
        }catch(MoneyException e){
            
            e.printStackTrace();
            System.out.println("跟我洗一个月的碗吧!");
        }    
        
    }

    public static void eat(int money)throws  MoneyException{
        
        if(money<10){

             throw new MoneyException("吃霸王餐");
        }
        System.out.println("吃香喷喷的饭吧!");
    }
}

 

 



5. finally语句

  3)定义:

      无论程序正常还是异常,都会执行finally,除非jvm停止(System.exit(0))

  2)运用:

      因为我们不能对一个文件同时进行修改和删除,当一个人在删除文件时代码报错,这个时候我们就要释放资源(finally一般用于释放资源)

  

  3)语法:

      a.try{ // 可能发生异常的代码 } catch( 异常类的类型 e ){ // 当发生指定异常的时候的处理代码 }catch...

        比较适合用于专门的处理异常的代码,不适合释放资源的代码

 

      b.try{  } catch(){} finally{ // 释放资源的代码 }

        比较适合用于既要处理异常又有资源释放的代码

 

      C.try{  }finally{ // 释放资源 }

        比较适合处理的都是运行时异常且有资源释放的代码。

 

 

 

以上是关于22. 异常(Eception)的主要内容,如果未能解决你的问题,请参考以下文章

kettle 7.0 部署报错 A JAVA Eception has occurred

使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段

异常和TCP通讯

片段中的Android致命异常

mvn命令异常:An error has occurred in Javadoc report generation: Unable to find javadoc command异常已解决(代码片段

mvn命令异常:An error has occurred in Javadoc report generation: Unable to find javadoc command异常已解决(代码片段