毕向东之异常

/*异常:是对问题的处理,将问题进行对象的封装。
 异常体系: Throwable
             |--Error
             |--Exception
                 |--RuntimeException
只有异常体系中的所有类以及建立的对象才具备可抛性
throws和throw的用法:throw定义在函数内,用于抛出异常对象
                  throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则编译失败。
注意:RuntimeException除外,也就是说,函数内如果抛出的是RuntimeException异常,函数上可以不用声明
如果函数声明了异常,调用者需要进行处理,处理方式可以throws 可以try.
------------------------------
异常有两种:
    编译时被检测异常:该异常在编译时,如果没有处理(没有抛也没有try),编译失败。该异常被标识,代表这可以被处理。
    运行时异常(编译时不检测):在编译时,不需要处理,编译器不检查。该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
---------------------------------    
异常的处理方式:
 java提供了特有的语句进行处理:   不可以单独使用
  try{
     需要被检测的代码;
  }catch(异常类 变量){
     处理异常的代码;(处理方式)
  }finally{
    一定会执行的语句;//通常用来关闭资源
  }
    在catch中写return的时候,处理完个异常时就执行return跳出这个函数,不会执行该函数下面的语句,但会执行finally里面的语句。但是当把catch
    中的return改为 Ststem.exit(0);(jvm结束)时,下面的finally语句就不会执行。
---------------------------
自定义异常:
    定义类继承Exception或RuntimeException
    1.为了让该自定义类具备可抛性,2.让该类具备操作异常的共性方法。
    当要定义自定义异常的信息时,可以使用父类已经定义好的功能,将异常信息传递给父类的构造函数。
    class MyException extends Exception{
        MyException(String message){
            super(message);
        }
    }
自定义异常的好处:1.将问题进行封装。2.将正常流程代码和问题处理代码相分离,方便于阅读。

异常的处理原则:
    1.处理方式有两种:try 或者 throws
    2.调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应多个catch
    3.多个catch,父类的catch放到最下面
    4.catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句,也不要不写
    5.当捕捉到的异常,本功能吹了不了时,可以继续在catch中抛出
3.对捕捉到的异常对象进行常见的方法操作:String getMessage();
*/
public class Test1{
    public static void main(String[] args){
        Demo d=new Demo();
        try{
            int x=d.div(4,0);//new AritchmeticException();
            System.out.println("x="+x);//出现异常就不会执行异常处下面你的程序 异常被捕捉就跳转了
        }
        catch(Exception e){//捕捉异常 = new AritchmeticException(); 
            System.out.println("除零了!");
            System.out.println(e.getMessage());// 异常信息(by zero)
            System.out.println(e.toString());// 异常名称:异常信息
            e.printStackTrace();//异常名称,异常信息,异常出现的位置。
            //其实jvm默认的异常处理机制就是在调用printStackTrace方法,打印异常的堆栈的跟踪信息
        }
        System.out.println("程序结束");
    }
}
class Demo{
    int div(int a,int b){//会把异常交给调用它的对象处理
        return a/b;
    }
}

 

 

/*对于多异常的处理:
 1.声明异常时,建议声明更具体的异常,这样处理的可以更具体.
 2.用throws声明几个异常,(如果用catch处理)就对应有几个catch块进行处理,不要定义多余的catch块。
   如果多个catch块中的异常出现异常的关系,父类异常catch块放在在下面。(catch块是按照顺序执行的)
   
 对于异常   要么抛   要么try
 */
public class Test2 {

    public static void main(String[] args) {
        Demo2 d=new Demo2();
        try{
            int x=d.div(4, 0);
            System.out.println("x="+x);
        }catch(ArithmeticException e){
            System.out.println(e.toString());
            System.out.println("除零了");
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println(e.toString());
            System.out.println("下标越界了");
        }
        System.out.println("程序结束");
    }

}
class Demo2{
    int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException{
        int[] arr=new int[a];
        System.out.println(arr[4]);
        return a/b;
    }
}

 

 

/*因为项目中会出现特有的问题,而这些问题并未被java描述并封装成对象,所以可以将这些特有的问题,进行自定义的异常封装
 自定义异常:
 1.当在函数中出现了throw抛出异常对象,那么就必须要给对应的处理动作。
 2.要么再函数上声明让调用者处理,要么在内部try catch 处理。
 一般情况下,在函数内出现异常,函数上需要声明
 
 如何自定义异常信息呢?
 因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息通过super(信息)传递给父类
 就可以直接通过getMessage()方法获取自定义的异常信息
 
自定义异常:
必须是自定义类继承Eclipse(原因:异常体系有一个特点:异常类和异常对象都被抛出,他们都具备可抛性,
但是这个可抛性是Throwable这个体系独有的特点,只有这个体系中的类和对象才可以被throws和throw操作)

throws和throw的区别:
throws用在函数上,throw用在函数内
throws后面跟的是异常类,可以跟多个,用逗号隔开; throw后跟的是异常对象。
 */

//在本程序中对除数的负数也认为是无法进行运算的  那么就需要对这个问题进行自定义的描述。
public class Test3 {

    public static void main(String[] args) {
        Demo3 d=new Demo3();
        try{
            int x=d.div(4, -1);
            System.out.println("x="+x);
        }catch(FuShuException e){
            System.out.println(e.getMessage());
            System.out.println("错误的负数是:"+e.getValue());
            System.out.println("出现负数了");
        }
        
        System.out.println("程序结束");
    }
}
class Demo3{
    int div(int a,int b)throws FuShuException{
        if(b<0)
            throw new FuShuException("构造方法——自定义的负数异常",b);//手动通过throw关键字抛出一个自定义异常对象
        return a/b;
    }
}
class FuShuException extends Exception{//只有继承Exception才能抛出异常
    private int value;
    public FuShuException(){
        super();
    }
    public FuShuException(String message, int value){
        super(message);//将信息传递给父类中的构造函数
        //System.out.println(message);    
        //b为自定义的函数的信息 父类没有的
        this.value=value;
    }
    public int getValue(){
        return value;
    }
}

 

 

/*对于异常分两种:
 1.编译时被检测的异常
 2.编译时不能被检测的异常(运行时异常,RuntimeException) 运行时异常
     运行时异常:当运行出现这个异常时,程序就不会继续往下执行
 */
public class Test4 {

    public static void main(String[] args){
        Demo4 d=new Demo4();
        try{
            int x=d.div(4,-1);
            System.out.println("x="+x);
        }catch(FuShuException4 e){//处理异常
            System.out.println(e.getMessage());
        }catch(ArithmeticException e){
            System.out.println(e.getMessage());
        }
        System.out.println("程序结束");
    }
}
class Demo4{
    public int div(int a,int b)/*throws FuShuException4*/{
        
        
        if(b<0)
            throw new FuShuException4("负数啦");//创建一个异常
        if(b==0)
            throw new ArithmeticException("除数为零啦");
        return a/b;
    }
}
class FuShuException4 extends RuntimeException{
    public FuShuException4(String message){
        super(message);
    }
}

 

 

/*try catch finally的三种格式用法:
 *1.try{} catch(){}    2.try{} catch(){}finally{}  3.try{}finally{}
 catch用来处理异常 没有解决就需要抛出问题(throws是抛出问题给别人处理,不需要自己处理),throw则是抛出问题(new 一个异常出来创建问题)
 而 finally不是处理问题
 
 异常在子父类覆盖中的体现:
 1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类(不能抛父类没有的异常)。
 2.如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集。
 3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
     如果子类方法发生了异常,就必须要进行try处理,绝对不能抛。
     
 当有异常时我们进行处理,异常就回被解决,但程序会继续往下执行,这样当有时候这种异常没有解决的必要时,就可以继承运行时异常
 继承RuntimeException时,就不需要catch去处理,因为编译时不会报错
 */
public class Test5 {

    public static void main(String[] args) {
        Rec r=new Rec(3,-1);//出现异常就跳转带到异常处执行,不会执行r.getArea();
        r.getArea();
        System.out.println("over");
    }

}
class Rec implements Shape{
    private int len,wid;
    public Rec(int len,int wid){
        if(len<=0||wid<=0){
            throw new NoValueException("出现非法值");
        }
        this.len=len;
        this.wid=wid;
    }
    public void getArea(){
        System.out.println(len*wid);
    }
}
class NoValueException extends RuntimeException{
    public NoValueException(String message){
        super(message);
    }
}
interface Shape{
    public void getArea();
}

 

posted @ 2016-05-31 12:43  ts-android  阅读(291)  评论(0编辑  收藏  举报