黑马程序员_Java基础_异常处理

------- android培训java培训、期待与您交流! ----------



异常:就是程序在运行时出现不正常的情况
异常由来:问题也是显示生活中的一个具体的事物,也可以通过java类的形式进行描述,并封装对象,
 其实就是java对不正常情况进行描述后的对象体现。
 
 
1.对于问题的划分:两种:一种是严重的问题,一种是非常严重的问题
对于严重的 Java通过Error类进行描述
 对于Erro一般不编写针对性的代码对其进行处理
 
对于不严重的,java通过Exception类进行描述
 对于Exception可以使用针对性的处理fanghi进行处理
 
无论Error或者Exception都具有一些共性内容。
比如:不正常情况的信息,引发原因等
Throwable
     |--Error
     |--Exception
2.异常的处理
Java提供了特有的语句进行处理
try{
 需要被检测的代码;
}catch(异常类  变量){
 处理异常的代码,(处理方式)
}
finally{
 一定会执行的代码;
}

3.对捕获的异常对象进行常见的方法操作:
String getMessage();    获取异常信息
在函数上声明异常,
以便于提高安全性,让调用出进行处理,不处理编译失败。 
例子1: 
 
public class ExceptionDemo {

    public static void main(String[] args) {

        

//      int a = 4/0;

        /*

         *当被除数为0时,在编译期间是不会出现异常的,等到运行时会报出 ArithmeticException异常

         */

        

        try{

            int a = 4/0;

            System.out.println(a);

        }catch(Exception e){

            System.out.println(e.getMessage());  //by zero;

            System.out.println(e.toString());//异常名称:异常信息

            //java.lang.ArithmeticException: / by zero

            e.printStackTrace();  //异常名称:异常信息,异常出现的位置。

            //其实jvm默认的异常处理机制,就是调用printStackTrace();

            //打印异常的堆栈的跟踪信息

            //java.lang.ArithmeticException: / by zero

            //at day12_Exception.ExceptionDemo.main(ExceptionDemo.java:36)

        }

        try {

            div(4,1);

        } catch (Exception e) {

            e.printStackTrace();

        }

        

//      byte[] by = new byte[1024*1024*600];

        /*

         * 当定义的数组超出虚拟机的内存容量是,会出现Error异常,虚拟机不理不了会自动关闭

         */


    }

    //在功能上通过throws的关键字声明了该功能有可能会出现问题

    public static int div(int a,int b)throws Exception{

        return a/b;

    }

    


}
对多异常的处理
1.声明异常时,建议声明更为具体的异常,这样处理的可以更具体
2.对方声明多个异常,就对应有几个catch快,不要定义多余的catch快。
 如果多个catch快中的异常出现继承关系,父类异常catch快放在最下面。
建立在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句e.printStackTrace();
也不要简单的书写一条输出语句。 

例子2: 
<strong>public class ExceptionDemo2 {

    public static void main(String[] args) {

        Demo d = new Demo();

        try{

//          int s = d.div(4,1);             java.lang.ArrayIndexOutOfBoundsException: 4

            int s = d.div(5, 0);        //java.lang.ArithmeticException: / by zero

            System.out.println(s);

        }catch(ArithmeticException e){

            e.printStackTrace();

        }catch(ArrayIndexOutOfBoundsException e){

            e.printStackTrace();

        }


    }

    

}

class Demo{

      int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException{

        byte[] by = new byte[a];

        System.out.println(by[4]);

        return a/b;

    }

}</strong>

 因为项目中会出现特有的问题。
 而这些问题并未被java所描述并封装对象,
 所以对这些特有的问题可以按照Java的问题封装的思想
 将特有的问题,进行自定义的异常封装
 
 自定义异常。
 
 需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的
 那么就需要对这个问题进行自定义的描述。

 
 当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作
 要么在内部try  catch处理
 要么在函数上声明让调用者处理
 
 一般情况在函数内出现异常,函数上需要声明。
 
 发现打印的结果中只有异常的名称,却没有异常的信息。
 因为自定义的异常并未定义信息。
 
 如何定义异常信息呢?
 因为父类中已经把异常信息的操作都完成了。
 所以子类只要在构造时,及异常信息传递一个父类通过super语句
 那么就可以直接通过getMessage方法获取自定义的异常信息。
 
 自定义异常:
 必须是自定义类继承Exception
 
 继承Exception原因:
 异常体系有一个特点:因为异常类和异常对象都被抛出、
 他们都具备可抛性,这个可抛性是Throwable这个体系中独有特点
 
 只有这个体系中类和对象才可以被throws和throws操作
 
 throw和throws的区别:
 throws使用在函数上。
 throw使用在函数内。
 
 throw后面跟的异常类,可以跟多个,用逗号隔开。
 throw后跟的是异常对象,
 例子3:
 
<strong>class FushuException extends Exception{

    private int value;

    FushuException(String msg,int value){

        super(msg);

        this.value=value;

    }

    public int getValue(){

        return value;

    }

}


class Demo1{

      int div(int a,int b)throws FushuException{

          if(b<0)

              throw new FushuException("被除数为负数异常",b);

        return a/b;

    }

}


public class ExceptionDemo3 {


    public static void main(String[] args) {

        Demo1 d = new Demo1();

        try {

            d.div(4, -1);

        } catch (FushuException e) {

            e.printStackTrace();

            System.out.println("出现异常除数:" + e.getValue());

        }


    }


}

/*

 运行结果:day12_Exception.FushuException: 被除数为负数异常

    at day12_Exception.Demo1.div(ExceptionDemo3.java:19)

    at day12_Exception.ExceptionDemo3.main(ExceptionDemo3.java:29)

出现异常除数:-1

*/</strong>

 Exception中有一个特殊的子类异常 RuntimeException运行时异常
 
  如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过
 
  如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过
 
 之所以不用在函数声明,是因为不需要让调用者处理
 
 当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后
 
 对代码进行修正
 
自定义异常时,如果该异常的发生,无法在继续进行预算,
就让自定义异常继承RuntimeException、
对于异常分梁两种:
1,在编译时被检测的异常
2,编译时不被检测的异常(运行时异常,RuntimeException以及其子类)

记住一点:catchg是用于处理异常的,如果明日又catch就代表异常没有被处理过,如果该异常是检测时异常,那么必须声明;
第一种格式:
try{
}catch(){
第二种格式:
try{
}catch(){
}finally{
}
第三种格式:
try{
}finally{
}
自定义RuntimeException异常 
例子4:
 
<strong>class FushuException extends RuntimeException {

    FushuException(String msg) {

        super(msg);

    }

}


class Demo4 {

    public int div(int a, int b) throws ArithmeticException{

        if (b < 0)

            throw new FushuException("除数为负数异常");

        if (b == 0)

            throw new ArithmeticException("除数为0异常");

        

        return a / b; 

    }

}


public class ExceptionDemo4 {


    public static void main(String[] args) {

        try {

            Demo4 d = new Demo4();

            int s = d.div(4, -8);

            System.out.println(s);

        } catch (ArithmeticException e) {

            e.printStackTrace();

        } finally{

            System.out.println("我是一定被执行的");

        }

        System.out.println("over");

    }


}</strong>
异常在子父类覆盖中的体现
 1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
 2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
 3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常,】
 如果子类方法发生了异常, 就必须要进行try处理,绝对不能抛出。
例子5: 
<strong>class AException extends Exception {


}


class BException extends AException {


}


class CException extends Exception {


}


/*

 * Exception 

 * |--AException 

 *      |--BException 

 * |--CException

 */


class Fu {

    void show() throws AException {

    }

}


class Zi extends Fu {

    void show() throws BException {

    }

}


class Test {

    void function(Fu f) {

        try {

            f.show();

        } catch (AException e) {

            e.printStackTrace();

        }

    }

}


public class ExceptionDemo5 {

    public static void main(String[] args) {

        Test t = new Test();

        t.function(new Zi());

    }


}</strong>

当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,都在编译失败、
 注意:RuntimeException除外,也就是说,函数内如果抛出的RuntimeException异常,函数上可以不用声明。
 
 
 注意:
 1.finally中定义的通常是关闭资源代码,因为资源必须关闭
 2.finally只有一种情况不会执行,当执行代码到System.exit(0); finally不会执行
 
异常的好处:
1.将问题进行封装
2.将正常流程代码和问题处理代码相分离,方便与阅读
异常的处理原则:
1.处理方式有两种:try或者throws
2.调用到抛出异常的功能时,抛出几个,就处理几个
 一个try对应多个catch
3.多个catch,父类的catch放到最下面
4.catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句,以不要不写
当捕获到的异常,本功能处理不了时,可以继承在catch中抛出

异常的注意事项:
在子父类覆盖时:
1,子类抛出的异常必须是父类的异常的子类或者子集
2.如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛
 
//自定义异常

class InvalidValueException extends RuntimeException {

    InvalidValueException(String msg) {

        super(msg);

    }

}


// 图形接口

interface Shape {

    void getArea();

}


// 长方形

class Rec implements Shape {

    private int len, wide;


    Rec(int len, int wide) {

        if (len <= 0 || wide <= 0)

            throw new InvalidValueException("无效参数异常");

        this.len = len;

        this.wide = wide;

    }


    @Override

    public void getArea() {

        System.out.println(len * wide);

    }


}


// 圆形

class Circular implements Shape {

    private int r;

    public static final double PI = 3.14;

    Circular(int r){

        if(r<=0)

            throw new InvalidValueException("无效值异常");

        this.r = r;

    }

    @Override

    public void getArea() {

        System.out.println(r*r*PI);


    }


}


public class ExceptionTest {

    public static void main(String[] args) {

        

        Rec rec = new Rec(4,-1);

        rec.getArea();

        

        Circular c = new Circular(-9);

        c.getArea();

    }


}

 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值