Day07-08(异常)

异常

  • 在程序中如果有异常,jvm会在出现异常的地方New一个异常对象,并抛出
  • 异常在Java中以类的形式存在,每一个异常类都可以创建异常对象
  • 体系类图
    在这里插入图片描述
    Exception分为运行时异常和编译时异常,编译时异常,如果在编写代码时不进行异常出来,则会编译报错

在这里插入图片描述
比如:

/**
 * 报错原因是dosome()抛出的是编译时异常,所以要进行异常处理
 */
public class Mytest01 {
    public static void main(String[] args) {
        try {
            dosome();
        } catch (GSSException e) {
            e.printStackTrace();
        }
    }

    public static void dosome() throws GSSException {
        System.out.println("fjsdlj");
    }
}
  • 只要异常没有捕捉,就一直往上抛,后续代码不会执行

  • 捕捉异常之后,后续代码可以执行

  • catch可以写多个,括号内的异常类型必须是从小到大的顺序

1、jdk7新特性
catch块里面可以采用“|”或运算符(只有当异常类型不存在子类关系时2才需要这个特性)
在这里插入图片描述
2、在实际开发中,如何选择是throws还是catch捕获处理

  • 如果需要让调用者来处理,则选择throws,否则catch自己处理。

3、如何查看 异常的追踪信息,快速调试程序

  • 异常追踪信息,从上往下一行行的看,SUN公司的代码不用看(看包名),主要看自己编写的代码上的第一行。
  • 在这里插入图片描述

4、Throwable类常用方法:

  • public string getMessage():返回异常发生时的简要描述
  • public string toString():返回异常发生时的详细信息
  • public string getLocalizedMessage():返回异常对象的本地化信息。使用 Throwable 的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与 getMessage()返回的结果相同
  • public void printStackTrace():在控制台上打印 Throwable 对象封装的异常信息 ,后台打印异常堆栈追踪信息的时候,采用异步线程的方式

5、以下四种 情况finally不会执行。

  • finally语句块第一行发生了异常。
  • 在前面的代码中用了System.exit(int已退出程序。 exit 是带参函数 ;若该语句在异常语句之后,finally 会执行
  • 程序所在线程死亡
  • 关闭CPU

6、注意: 当 try 语句和 finally 语句中都有 return 语句时,在方法返回之前,finally 语句的内容将被执行,并且 finally 语句的返回值将会覆盖原始的返回值。如下:

public static int f(int value) {
    try {
        return value * value;
    } finally {
        if (value == 2) {
            return 0;
        }
    }
}

如果调用 f(2),返回值将是 0,因为 finally 语句的返回值覆盖了 try 语句块的返回值。

自定义异常

1、编写一个类继承Exception或者RuntimeException
2、提供两个构造方法,一个无参,一个带有String参数的
比如:

public class MyException extends Exception{
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}
public class MyException2 extends RuntimeException{
    public MyException2(String message) {
        super(message);
    }

    public MyException2() {
    }
}

测试类:

public class Test03 {
    public static void main(String[] args) {
        MyException e = new MyException("自定义异常");
        e.printStackTrace();
        System.out.println(e.getMessage());

        MyException2 e2 = new MyException2("自定义运行时异常");
        e2.printStackTrace();
        System.out.println(e2.getMessage());
    }
}

输出结果:

com.feng.exception.MyException: 自定义异常
	at com.feng.exception.Test03.main(Test03.java:5)
com.feng.exception.MyException2: 自定义运行时异常
	at com.feng.exception.Test03.main(Test03.java:9)
自定义异常
自定义运行时异常

使用异常技巧

1、异常处理不能代替简单的测试

  • 只在异常情况下使用异常

2、不要过分的细化异常
3、充分利用异常层次结构

  • 不要只抛出RuntimeException。应该寻找一个适合的子类或创建自己的异常类
  • 不要只捕获Throwable,否则,会使代码更难读,难维护
  • 检查项异常:不要为逻辑错误抛出这些异常
  • 如果一种异常可以转换成另外一个更加合适的异常,那么不要犹豫

4、不要压制异常

  • 不要忽略异常,如果每个异常都非常重要,就应该适当的进行处理
  • 在检查错误的时候,“苛刻”,要比放任更好
  • 不要羞于传递异常:更高层的方法通常可以更好地通知用户发生了错误,或者放弃不成功的命令。

异常与方法覆盖

1、重写之后的方法不能比重写之前的方法更多(更宽泛)的异常。

异常处理总结:

  • try:用于捕获异常,后面可以接零个或多个catch块,如果没有Catch块,必须要有一个Finally块
  • Catch块:用于处理捕获的异常
  • Finally:无论是否有异常或处理异常,都会执行。如果try块和catch块遇到return语句时,finally在返回之前被执行。
  • Finally可以用于释放资源,不要把改变控制流的语句(return,throw,break,continue)放在finally中
  • throws:在方法声明位置上使用,表示上报异常信息给调用者
  • throw:手动抛异常

作业

在这里插入图片描述
自定义异常类:

public class RegisterException extends Exception{
    public RegisterException(String message) {
        super(message);
    }

    public RegisterException() {
    }
}

注册

public class UserService {

    public void register(String username, String password) throws RegisterException {
        //判断为空最好放在前面,因为||运算一个为真后面就会判断了,判断为空最好null放在前面: null = username
        if (null == username || username.length() < 6 || username.length() > 14) {
            throw new RegisterException("用户名要求长度在6-14之间");
        }
        System.out.println("注册成功!欢迎:" + username);
    }
}

测试

public class MyRegister {
    public static void main(String[] args) {
        UserService userService = new UserService();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String name = scanner.nextLine();
        System.out.println("请输入密码:");
        String pwd = scanner.nextLine();
        try {
            userService.register(name,pwd);
        } catch (RegisterException e) {
            e.printStackTrace();
        }
    }
}

结果:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值