JavaSE_day15:异常和处理异常

今天学习的异常与异常处理,异常处理大致分为两种,那么先来看一看异常分为几类;异常分为:Error和Exception两种,其父类都是Throwable,然后继承父类的error错误是比较严重的错误,而Exception是通过bubu或异常,让程序可以进行恢复正常运行的。

典型的error:

1.方法递归调用时,会发生栈内存溢出的错误,即StackOverFlowError。

举例看一下:

public class ErrerDemo {
    public static void main(String[] args) {
        test();   //Exception in thread "main" java.lang.StackOverflowError
    }
    public static void test() {
        test();
    }
}
当调用这个test方法的时候就会出现StackOverFlowError异常。这种异常几乎无法改变,因为他会耗尽你内存,最终而结束

2.不断的new对象,会出现堆内存溢出问题,即OutOfMemoryError。

代码举例:

public class ErrorDemo2 {
    private static List<String[]> list=new ArrayList<String[]>();
    public static void main(String[] args) {
        for(int x=0;x<100000;x++) {
            list.add(new String[10000]);
            //Exception in thread "main" java.lang.OutOfMemoryError
        }
    }
}
当给list集合不断new新对象的时候,就会出现堆内存溢出问题,就是上边的Exception in thread “main” Java.lang.OutOfMemeryError错误。

现在来看下异常Exception:

Exception 异常的的父类是Throwable,在程序出现异常的时候,我们可以捕捉到异常,可以使程序恢复运行。异常可以分成两类:
1.是检查异常(check),

             Throwable  Exception以及他的子类,检查异常需要强制使用try  catch或者throws一起使用。
2.为检查异常(uncheck),

            RuntimeException,或者他的子类

异常的处理:

1.消极处理:这种异常必须手动在方法声明上加上【throws  Exception】,但是这种情况弊端比较大,就是如果一个方法在最底层的话,每一次调用的方法都必须在方法声明上加上【throws Exception】,过程比较繁琐,所以大多数不太使用

public class ExceptionDemo {
    public static void mian(String[] args) throws Exception{
        m1();
    }
    public static void m1()throws Exception {
        m2();
    }
    public static void m2() throws Exception{
       m3();
    }
    public static void m3() throws Exception {
        throw new Exception("捕获异常,,,,,,");
    }
}

这个就是说底层的m3方法出现了异常,如果是在方法声明上加【throws Exception】,那么就会出现上述情况,每一个调用的方法都要写【throws Exception】,所以很麻烦。

2.积极处理:这种异常是在可能出现异常的地方加上try...catch代码块。(常常是运行时期异常RuntimeException,必须是RuntimeException或者是他的自类)

      语法:      

          try{

        //可能出现异常的代码      

} catch(Exception e){

   //捕获异常的代码

} 

意思就是当可能出现问题的代码块没有出现问题的时候,就会跳过catch语句,如果真的有错误,就会进入catch进行捕捉异常。

代码举例看一下:

public class ExceptionDemo2 {
    public static void m1()  {
        m2();
    }
    public static void m2()  {
           m3();
    }
    public static void m3()   {
        try {
            throw new Exception("捕获异常,,,,,,");
        } catch (Exception e) {
            System.out.println("出现异常了......");
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
    public static void main (String[] args)  {
        m1();
    }
}

此处的e.getMessage():捕获异常信息

e.printStackTrace():打印出现异常的地方

主动抛出异常:

  throws  new 异常    //此处的异常必须是Exception或者他的子类

public class ExceptionDemo3 {
    public static void m1(int a) {
        if(a<=0) {
            throw new RuntimeException("这个a它必须要大于0 !");
        }
        System.out.println("陈小帅");                                                                        //语句1
    }
    public static void main(String[] args){
        try{
            m1(0);    
        }catch(Exception e) {                                                                                    //语句3
            System.out.println(e.getMessage());                                                        //语句2
            e.printStackTrace();
        }
    }
}
在这里主动抛出的是RuntimeException异常,就是当m1()的参数大于0的时候,在运行时就不会出现错误,

那么他就会在执行语句1,就会输出【陈小帅】,如果给m1的参数是0或者负数,程序就会跳过语句1,到达语句3,执行catch语句,从而打印语句2.

异常对象的常见方法:

 e.getMessage();获取异常信息

e.printStactTrace():打印异常的跟踪信息

异常的传播:

【异常的传播是方法调用的反方向进行的】

好,具体代码展示一下

public class ExceptionDemo4 {
    public static void main(String[] args) {
        System.out.println(1);
        m3();
        System.out.println(2); // 1 6 4 3
    }
    public static void m1() {
        System.out.println(3);
        throw new RuntimeException("异常的开始....");
    }
    public static void m2() {
        System.out.println(4);
        m1();
        System.out.println(5);
    }
    public static void m3() {
        System.out.println(6);
        m2();
        System.out.println(7);
    }
}

自定义异常:

class MyException extends Exception{   }  这个是检查异常

class MyException extends RuntimeException{  }   这个是未检查异常

【注意】:

1.与有返回值的方法连用时要注意,

// 有返回值的方法 与  try-catch连用出现的问题
public class Exception5 {
    public static int test(){
        try {
            Scanner scanner = new Scanner(System.in);
            int n = scanner.nextInt();
            int r = 1/n;
            return r;
        } catch (Exception e ) {
            System.out.println(e.getMessage());
            return -1; // 解决方法1: 在catch也写一个return返回结果
//            throw e; // 解决方法2: 把异常重新抛出
        }
    }
    public static void main(String[] args) {
        int r = test();
        System.out.println(r);
    }
}
重写方法与异常声明:

重写方法的时候,子类不能抛出比父类更多类型的异常,比如父类抛出的是RuntimeException异常,子类就不能抛出Exception异常(检查异常),但是可以不抛出异常(默认抛出的数量必父类的少)

以上声明只针对检查异常,如果子类和父类重写throws,不遵守以上声明(一般开发过程中,用为检查异常比较多,所以尽量将检查异常转换成未检查异常。)

【finally关键字】

语法:
```java
   try {
      ...
   } catch(Exception e) {

   } finally {
      // 无论出现异常与否,总会被执行的代码
   }
```

如果说try catch中和finally都有return返回值,结果一finally为准

【注意】:如果try中有return,而finally中对try中的return值进行修改的话,结果并不影响try中的return值,所以最终的输出结果是try中的return值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值