【JAVA学习笔记】异常

2021-04-23  本文已影响0人  Geekero

学习自华为开发者学院陈璇老师的JAVA系列课程

一、try--catch--finally

try{
    //尝试执行,但可能出现异常的代码
}catch(Exception e){
    //捕获异常,对异常做处理
    System.err.println(....);
    System.exit(1);
}finally{
    //是否异常,异常是否捕获到都会执行
}

finally无论是否异常,异常是否正确捕获到都会执行,但是唯一不执行的就是catch完异常后System.exit(1) 中断程序,退出Java虚拟机

先执行finally, 然后再return结束方法

输出异常的堆栈信息:

e.printStackTrace()  

返回异常信息描述字符串,是printStackTrace()输出信息的一部分 :

e.printStackTrace()  

常见异常:


注意:
try--catch--finally结构中try语句块是必须的,catch、finally语句均可选,但两种必须至少有一个出现一次

多重catch块
引发多种类型的异常

import java.util.Scanner;

public class PrintSubName {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入课程代号(1~3之间的数字):");
        try {
            int num = input.nextInt();
            switch (num) {
                case 1:
                    System.out.println("Java 基础语法");
                    break;
                case 2:
                    System.out.println("Java OOP");
                    break;
                case 3:
                    System.out.println("Java 高级特性");

                    break;
            }
        }catch (Exception e) {
            System.out.println("输入格式不正确,课程代码必须是1~3之间的数字!");
            e.printStackTrace();
        }finally {
            System.out.println("欢迎提出建议!");
        }

    }
}

二、使用throws声明异常

throws 声明某个方法可能抛出的各种异常,多种异常用逗号隔开
方式1:调用者处理异常
方式2:调用者继续声明异常

import java.net.Socket;
import java.util.InputMismatchException;
import java.util.Scanner;

//使用throws声明异常
public class CalcTest {
    //两个数的除法运算
    //通过throws声明方法可能抛出的各种异常,多个异常之间用逗号隔开
    public void divide() throws InputMismatchException, ArithmeticException{
        Scanner in = new Scanner(System.in);
        System.out.print("请输入被除数:");
        int num1 = in.nextInt();
        System.out.print("请输入输出:");
        int num2 = in.nextInt();
        System.out.println(num1 + "/" + num2+"=" + num1/num2);
    }

//    public static void main(String[] args) {
//
//        CalcTest calc = new CalcTest();
//        //方式一:调用者直接处理掉异常
//        try {
//            calc.divide();
////            int num1 = in.nextInt();
////            System.out.print("请输入输出:");
////            int num2 = in.nextInt();
////            System.out.println(num1 + "/" + num2+"=" + num1/num2);
//        }catch(InputMismatchException e) {
//            //捕获异常,对异常进行处理
//            System.err.println("出现错误:被除数和输出必须为整数!");
//        }catch (ArithmeticException e) {
//            //捕获异常,对异常进行处理
//            System.err.println("出现错误:除数不能为零!");
//        }catch (Exception e){
//            //捕获异常,对异常进行处理
//            System.err.println("出现错误, 非法操作!");
//        }finally {
//            System.out.println("感谢使用本程序!");
//        }
//    }
    public static void main(String[] args) throws InputMismatchException, ArithmeticException {
        CalcTest calc = new CalcTest();
        //方式二:调用者不处理掉异常,继续声明。最终main()声明的异常由JVM处理
        calc.divide();
    }
}

三、使用throw抛出异常

//人类
public class Person {
    private String name;
    private int age;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) throws Exception {
        if (age<=100 && age>=1){
            this.age = age;
        }else {
            throw new Exception("年龄必须在1~100之间!");
        }
    }

    public String getSex() {
        return sex;
    }

    //性别只能是“男”或“女”,其他性别字符串报异常
    //使用throw抛出异常
    public void setSex(String sex) throws Exception {
        if (sex.equals("男")||sex.equals("女")) {
            this.sex = sex;
        }else {
            //写法1:
//            Exception e = new Exception("性别只能为男女!");
//            throw e;
            //写法2:
            //当使用throw显式抛出异常,必须对异常处理,或throws声明异常
            throw new Exception("性别只能为男女!");
        }
    }

    //个人信息介绍
    public void print() {
        System.out.println(this.getName()+"-"+this.getSex()+"-"+this.getAge());
    }

    public static void main(String[] args) {
        Person p = new Person();
        //当调用的方法有throws抛出异常,必须对异常处理,或throws声明异常
        try {
            p.setSex("男");
            p.setAge(0);
            p.print();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、异常体系结构

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 不处理Checked异常,编译无法通过。1. throws  2.try--catch捕获异常和处理异常
 */
public class TestIO {
    public static void main(String[] args) {
        FileInputStream fis = null;
        // 创建指定文件的流
        try {
            fis = new FileInputStream(new File("accp.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

五、自定义异常

继承Throwable、Exception RuntimeException类


AgeException.java
public class AgeException extends Exception {
    public AgeException(){}
    public AgeException(String message){
        super(message);
    }
}

SexException.java

//自定义异常类(Person类性别赋值异常)
public class SexException extends Exception {
    public SexException(){}
    //由特定异常信息构建异常对象
    public SexException(String message){
        super(message);
    }
}

Person.java

//人类
public class Person {
    private String name;
    private int age;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) throws AgeException {
        if (age<=100 && age>=1){
            this.age = age;
        }else {
            throw new AgeException("年龄必须在1~100之间!");
        }
    }

    public String getSex() {
        return sex;
    }

    //性别只能是“男”或“女”,其他性别字符串报异常
    //使用throw抛出异常(SexException--性别赋值异常)
    public void setSex(String sex) throws SexException {
        if (sex.equals("男")||sex.equals("女")) {
            this.sex = sex;
        }else {
            //写法1:
//            Exception e = new Exception("性别只能为男女!");
//            throw e;
            //写法2:
            //当使用throw显式抛出异常,必须对异常处理,或throws声明异常
//            throw new Exception("性别只能为男女!");
            throw new SexException("性别只能为男女!");
        }
    }

    //个人信息介绍
    public void print() {
        System.out.println(this.getName()+"-"+this.getSex()+"-"+this.getAge());
    }

    public static void main(String[] args) {
        Person p = new Person();
        //当调用的方法有throws抛出异常,必须对异常处理,或throws声明异常
        try {
            p.setSex("boy");
        } catch (SexException e) {
            e.printStackTrace();
        }
        try {
            p.setAge(0);
        } catch (AgeException e) {
            e.printStackTrace();
        }
        p.print();

    }
}

六、异常链 和 异常处理原则

6.1 异常链


异常链:创建了新的异常,但却保留了原有异常的信息(jdk1.4以后的特性)

6.2 异常处理原则

  1. 异常处理与性能(在没有异常时,异常处理对性能影响不大)
    - 整个代码段会被压在一个方法栈的地方(一块内存区域),JVM在读取方法时,如果发现有try catch触发异常,就会在方法的方法栈里面去找catch来进行执行
    - 但是通过throws声明和throw异常的话,JVM会顺着方法的调用,一直逐层去方法调用,到最后定位到相应的方法栈里的方法体找catch,对性能产生影响。
  2. 异常只能用于非正常情况
  3. 需要对捕获的异常做处理(如果有能力处理就进行处理,尽量不要往外抛出异常)
  4. 不要将过于庞大的代码块放在try中
  5. 在catch中指定具体的异常类型
上一篇 下一篇

猜你喜欢

热点阅读