Java SE核心API(11) —— 异常处理

版权声明:本文为博主原创文章,遵循GPL开源协议精神,转载请注明出处。 https://blog.csdn.net/Robot__Man/article/details/80462149

一、异常的捕获和处理

  Java异常结构中定义有Throwable类,Exception和Error是其派生的两个子类。其中Exception表示由于网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常;而Error表示Java运行时环境出现的错误,例如:JVM内存资源耗尽等。

1.1 try-catch

package day08;
/**
 * java异常捕获机制中的try-catch
 * try块是用来括上可能出错的代码片段
 * catch块是用来捕获try块中代码抛出的错误并解决。
 * @author xxx
 *
 */
public class ExceptionDemo1 {
    public static void main(String[] args) {
        System.out.println("程序开始了");

        try {
            //String str = null;
            //String str ="";
            String str = "a";
            /*
             * JVM在执行代码的过程中若发现了一个异常,则会实例化这种情况的异常实例,
             * 并将代码整个执行过程完整设置到异常中来表示该错误报告,设置完毕后将该
             * 异常抛出。若抛出异常的这句代码有被try包围,则JVM会检查catch中
             * 是否有关注该异常,关注则交给catch解决,否则会将异常抛出到当前方法外。
             * 由调用当前方法的代码解决该异常。
             */
            System.out.println(str.length());
            System.out.println(str.charAt(0));
            System.out.println(Integer.parseInt(str));
        }catch(NullPointerException e){
            System.out.println("出现了空指针");
        }catch(StringIndexOutOfBoundsException e){
            System.out.println("字符串下标越界了");
        /*
         * 应在最后一个catch中捕获Exception,避免因未捕获异常导致程序中断。  
         * 当多个catch捕获不同异常时,这些异常间存在继承关系,那么子类异常要在上
         * 先行捕获。父类异常在下。
         */
        }catch(Exception e) {
            System.out.println("出现未知错误");
        }
        System.out.println("程序结束了");
    }
}

1.2 finally

package day08;
/**
 * finally块
 * finally块定义在异常捕获机制的最后
 * 可以直接跟在try块之后或者最后一个catch块之后。
 * finally块中的代码一定执行,无论try块中的代码是否抛出异常,所以通常会
 * 把释放资源等操作放在finally中,例如关闭流。
 * @author xxx
 *
 */
public class ExceptionDemo2 {
    public static void main(String[] args) {
        System.out.println("程序开始了");

        try {
            //String str = null;
            String str = "";
            System.out.println(str.length());       
        }catch(Exception e) {
            System.out.println("出错了");
        }finally {
            System.out.println("finally中的代码执行了");
        }

        System.out.println("程序结束了");
    }
}
package day08;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

/**
 * finally对于流的处理
 * @author xxx
 *
 */
public class ExceptionDemo3 {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(
                    new FileInputStream("src/day08/ExceptionDemo3.java")));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        }catch(Exception e) {
            System.out.println("出错了");
        }finally {
            if (br != null) {
                try {
                    br.close();
                }catch(Exception e) {
                    System.out.println("关闭流时出错");
                }
            }
        }
    }
}

1.3 throw与throws

package day08;
/**
 * 用来测试throw与throws
 * @author xxx
 *
 */
public class Person {
    private int age;

    public int getAge() {
        return age;
    }

    /*
     * 当一个方法中使用throw抛出一个异常时,就要在方法上使用throws声明该类
     * 异常的抛出以通知调用者解决。
     * 只有RuntimeException及其子类异常使用throw抛出时不强制要求必须使用
     * throws声明,其他异常都是强制要求的,否则编译不通过。
     */
    public void setAge(int age) throws IllegalAgeException{
        if (age < 0 || age > 100) {
            //throw new RuntimeException("年龄不合法");
            throw new IllegalAgeException("年龄不合法");
        }

        this.age = age;
    }       
}
package day08;
/**
 * 测试异常的抛出
 * @author xxx
 *
 */
public class ExceptionDemo4 {
    public static void main(String[] args){
        Person p = new Person();
        /*
         * 当调用一个含有throws声明异常抛出的方法时,编译器要求必须处理该异常。
         * 处理手段有两种:
         * 1、使用try-catch捕获并处理。
         * 2、在当前方法上继续使用throws声明该异常的抛出。但不要在main方法上抛异常,会被JVM杀掉当前进程退出。
         */
        try {
            p.setAge(20);
        } catch (IllegalAgeException e) {
            e.printStackTrace();
        }

        System.out.println("年龄为:"+p.getAge());
    }
}

1.4 重写方法时的throws

  如果使用继承时,在父类的某个方法上宣告了throws某些异常,而在子类别中重写该方法时,您可以:
  1、不处理异常(重新定义时不设定throws);
  2、可仅throws父类别中声明的部分异常;
  3、可throws父类方法中抛出异常的子类异常。
  但是不可以:
  1、throws出额外的异常;
  2、throws父类方法中抛出异常的父类异常。


二、RuntimeException

2.1 RuntimeException的特点

  Java异常可分为可检测异常,非检测异常。
  可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理或声明规则,不捕捉这个异常,编译器就通不过,不允许编译。
  非检测异常不遵循处理或者声明规则,在产生此类异常时,不一定非要采取任何适当操作,编译器不会检查是否已经解决了这样一个异常。

  RuntimeException类属于非检测异常,因为普通JVM操作引起的运行时异常随时可能发生,此类异常一般是由特定操作引发。但这些操作在java应用程序中会频繁出现,因此它们不受编译器检查与处理或声明规则的限制。

2.2 常见RuntimeException

  • IllegalArgumentException
      抛出的异常表明向方法传递了一个不合法或不正确的参数。  
  • NullPointerException
      当应用程序试图在需要对象的地方使用null时,抛出该异常。
  • ArrayIndexOutOfBoundsException
      当使用的数组下标超出数组允许范围时,抛出该异常。
  • ClassCastException
      当试图将对象强制转换为不是实例的子类时,抛出该异常。
  • NumberFormatException
      当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。  

三、异常常用API

3.1 printStackTrace

  void printStackTrace(),Throwable中定义了一个方法可以输出错误信息,用来跟踪异常事件发生时执行堆栈的内容。

3.2 getMessage

  String getMessage(),Throwable中定义了一个方法可以得到有关异常事件的信息。

package day08;
/**
 * Exception常用用法
 * @author xxx
 *
 */
public class ExceptionDemo5 {
    public static void main(String[] args) {
        System.out.println("程序开始了");

        try {
            String str = "abc";
            System.out.println(Integer.parseInt(str));
        } catch (Exception e) {
            //e.printStackTrace();
            System.out.println(e.getMessage());
        }

        System.out.println("程序结束了");
    }
}

四、自定义异常

  创建自定义异常类,语法格式:
  class [自定义异常类名] extends Exception{
  …
  }
  当定义好自定义异常后,我们可以通过Eclipse来自动生成相应的构造方法。

package day08;
/**
 * 年龄不合法异常
 * 
 * 自定义异常,通常是用来描述某个业务逻辑上出现的问题。
 * 自定义异常的名字应当做到见名知义
 * @author xxx
 *
 */
public class IllegalAgeException extends Exception{

    private static final long serialVersionUID = 1L;

    public IllegalAgeException() {
        super();
    }

    public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    public IllegalAgeException(String message, Throwable cause) {
        super(message, cause);
    }

    public IllegalAgeException(String message) {
        super(message);
    }

    public IllegalAgeException(Throwable cause) {
        super(cause);
    }

}

  上面自定义的异常在前面的代码Person类中有应用到。

猜你喜欢

转载自blog.csdn.net/Robot__Man/article/details/80462149