黑马程序员_异常

一、异常
     1、概念
          异常:就是程序在运行时出现不正常情况。
          异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。
  其实就是java对不正常情况进行描述后的对象体现。      
对于问题的划分:两种:一种是严重的问题,一种非严重的问题。

对于严重的,java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。

对与非严重的,java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。

无论Error或者Exception都具有一些共性内容。
比如:不正常情况的信息,引发原因等。

  异常的分类:
    1:编译时异常
           该异常在编译时期,如果没有处理,编译失败。该异常被标识,代表可以被处理
    2:运行时异常
        在编译时不需要处理,编译器不检查。该异常的发生,建议不处理,让程序停止,需要对代码进行修正


2、异常的处理
  2.1  throws:
     在函数上声明异常。便于提高安全性,让调用处进行处理。不处理编译失败。一旦使用throws声明抛出异常,程序无需使用
     使用throws处理异常不是真正处理异常而是推卸责任。谁调用的就会抛给谁。
格式:
[修饰符] [返回值类型] [方法名] throws XXException, XXXException...{}
class  Demo
{
      int  div(  int  a, int  b) throws  Exception //在功能上通过throws的关键字声明了该功能有可能会出现问题(Exception异常)。
     {
            return  a/b;
     }
}


    2.2使用throw抛出异常:
        如果程序中的数据、执行与既定的业务需求不符而产生的异常,必须由程序员来决定抛出,系统无法抛出这种异常。则应该使用throw语句,throw语句可以单独使用,它抛出的不是异常类,而是异常类的实例,而且每次只能抛一个异常实例。格式如下:
            throw new 异常类("描述信息");
             代码示例:
            /*
                需求:求两个数的和,当一个数小于等于0的时候,抛出异常
             */
             public class Deom{
                public static void main(String[] args)
                {
                    int sum = sum(-2, 3);
                    System.out.println(sum);
                }
                public static int sum(int a, int b)
                {
                    if(a <= 0 || b <= 0)
                        throw new RuntimeException("出现负数");
                    return a + b;
                }
             }
2.3java 提供了特有的语句进行处理。
try
{
     需要被检测的代码;
}
catch(异常类 变量)
{
     处理异常的代码;(处理方式)//当try中出现异常,catch捕捉到,此部分代码才会执行。
}
finally
{
     一定会执行的语句;
}
可以细分成3中格式:

第一个格式:
try
{
    
}
catch ()
{
}

第二个格式:
try
{
    
}
catch ()
{
}
finally
{

}

第三个格式:
try
{
    
}
finally
{
}
  catch对多异常的处理。

1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。 如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

     
          当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
          try
          {
               throw new AException();
          }
          catch (AException e)
          {
               throw e;
          }

          如果该异常处理不了,但并不属于该功能出现的异常。
          可以将异常转换后,在抛出和该功能相关的异常。

          或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,
          当调用者知道。并处理。也可以将捕获异常处理后,转换新的异常。
          try
          {
               throw new AException();
          }
          catch (AException e)
          {
               // 对AException处理。
               throw new BException();
          }


  finally中放什么样的代码?
        通常我们会用来释放资源。
        如果在方法返回之前,可以断开,那么就应该把断开的语句放到finally中,这样可以保证断开的语句总是执行。
        finally中不会执行的情况
        finally遇见了System.exit(0)时,就不会再执行了。因为System.exit(0)会把JVM停止了。
        try
        {
          System.exit(0)
        }
        finally
        {
          //不会执行
        }

     
  异常的好处:
     1,将问题进行封装。
     2,将正常流程代码和问题处理代码相分离,方便于阅读。

 异常处理机制:
    Java的异常处理机制可以让程序具有极好的容错性,让程序更加健壮。当程序运行出现意外情况时,系统会自动生成一个Exception对象来通知程序,从而实现将"业务功能实现代码"和"错误处理代码"分离,提供更好的可读性。


3,对捕获到的异常对象进行常见方法操作。
     getMessage():获取异常信息。
     toString();获取异常类名和异常信息,返回字符串。
     printStackTrace();获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
     printStackTrace(PrintStream s): 通常用该方法将异常内容保存在日志文件中,以便查阅




class   Demo
{
      int   div(   int   a, int   b) throws   Exception //在功能上通过throws的关键字声明了该功能有可能会出现问题。
     {
             return   a/b;
     }
}


public   class     ExceptionDemo
{
      public   static   void   main(String[] args)
     {
          Demo d =   new   Demo();
             try
          {
                 int   x = d.div(4,0);
              System.   out .println( "x="   +x);
          }
             catch   (Exception e) //Exception e = new ArithmeticException();
          {
              System.   out .println( "除零啦"   );
              System.   out .println(e.getMessage()); //  / by zero;
              System.   out .println(e.toString()); // 异常名称 : 异常信息。

              e.printStackTrace();   //异常名称,异常信息,异常出现的位置。
                                     //其实jvm默认的异常处理机制,就是在调用printStackTrace方法。
                                     //打印异常的堆栈的跟踪信息。
/*
java.lang.ArithmeticException: / by zero
              at Demo1. div(ExceptionDemo.java:5)
              at ExceptionDemo.main(ExceptionDemo.java:17)
*/

          }         
          

          System.   out .println( "over"   );

     }
}

4,自定义异常
因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。所以对于这些特有的问题可以按照java的对问题封装的思想。将特有的问题,进行自定义的异常封装。

自定义异常通常继承于Exception 或RuntimeException
     1.编译时异常,直接继承Exception
     2.运行时异常,直接继承RuntimeException
     
继承Exception原因:
     异常体系有一个特点:因为异常类和异常对象都被抛出。
     他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。

     只有这个体系中的类和对象才可以被throws和throw操作。

通过构造函数定义异常信息。

public   class   IllegalNameException   extends   Exception{   //编译时异常
//public class IllegalNameException extends RuntimeException{ //运行时异常
    
       //定义异常一般提供两个构造方法
       public   IllegalNameException(){}
    
    
       public   IllegalNameException(String msg){
            super (msg);
     }
    
}

//顾客相关的业务
public   class   CustomerService{
     
      //对外提供一个注册的方法
      public   void   register(String name)   throws   IllegalNameException{
          
             //完成注册
             if (name.length()<6){
              
                 //异常
                 //创建异常对象
                 //IllegalNameException e = new IllegalNameException("用户名长度不能少6位");
              
                 //手动抛出异常
                 //throw e;
                 throw   new   IllegalNameException ( "用户名长度不能少6位"   );
          }
          
             //如果代码能执行到此处,证明用户名是合法的.
          System.   out .println( "注册成功!"   );
          
     }
     
      public   static   void   main(String[] args){
          
             //假如用户提供的用户名如下
          String username =   "fdafdafdsa" ;
          
             //注册
          CustomerService cs =   new   CustomerService();
          
             try {
              cs. register(username);
          }   catch (IllegalNameException e){
              System.   out .println(e.getMessage());
          }
          
          
     }
     
}


5,throws和throw的区别
     throws使用在函数上,后面跟的异常类。可以跟多个。用逗号隔开。用于标识函数暴露出的异常
     throw使用在函数内,后跟的是异常对象。用于抛出异常对象

6,异常细节
RuntimeException 以及其子类如果在函数中被 throw 抛出,可以不用在函数上声明。
一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子 类。
如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常 的一个子集,不能抛出新的异常。
如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常,如果子类方法发生了异常,就必须要进行try处理,绝对不能抛
class AException extends  Exception
{
}

class BException extends AException
{
}

class CException extends Exception
{
}

class Fu
{
     void show()throws AException
     {
    
     }
}

class Test
{
     void function(Fu f)
     {
          try
          {
               f.show();
          }
          catch (AException e)
          {

          }
         
     }
}


class Zi extends Fu
{

     /*

              只能抛AException或者AException的子类异常BException
              不能抛CException
             */

     void show()throws CException
     {
         
     }
}


class 
{
     public static void main(String[] args)
     {
          Test t = new Test();
          t.function(new Zi());
     }
}

7,常见异常信息
     ArithmeticException(算术异常)
     OutOfMemoryError(内存溢出错误)
     IndexOutOfBoundsException索引出界
     IllegalStateException非法状态
     IllegalArgumentException非法参数
     NullPointerException空指针





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值