有关异常的处理、捕获、抛出、自定义

简介: 有关异常的处理、捕获、抛出、自定义

有关异常的处理、捕获、抛出、自定义


异常处理

什么时候使用异常

Throwable

Error 错误 无法专门处理

Exception 异常

受检异常 编译的时候,必须处理的异常,可以使用try-catch捕获异常,也可以通过throws在方法中声明抛出异常

非受检异常(运行时异常)

捕获异常 更重要

try-catch-finally

catch可以有多个,catch和finally至少存在一个

如果代码出现异常,异常代码后的代码不再执行,直接跳转到对应的catch代码块进行操作

不管代码是否有异常,finally中的逻辑都会执行,哪怕使用了return (使用System.exit() 退出程序,finally中代码不会执行)

package com.qfedu.exception;
public class App2 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    int a = 10;
    int b = 0;
    // 针对可能出异常的代码使用try包起来
    // 如果出异常,使用catch捕获异常
    // 出现异常后,出现异常的代码,后续的代码不会执行,跳转到catch语句块,执行其中的代码
    // 如果try括住的代码正常执行,不会进行catch代码块
    // 可以写多个catch 捕获不同的异常,如果代码发生异常,和catch后的异常进行比对,
    //    符合哪个具体的异常就进入哪个catch代码块中
    // 针对需要具体处理的异常,通过在catch后这是具体的异常可以捕获,但是我们不可能预见所以可能的异常,
    //    这时,就可以使用catch捕获Exception类型的异常,防止遗漏
    //    注意:父类的Exception异常一定要放在所有catch代码块的最后
    // 实际开发中,一般报异常了,会将异常信息记录到日志系统
    try {
      int c = a / b;
      System.out.println(c);
      // String str = null;
      String str = "hello";
      System.out.println(str.length());
      // ClassCastException
      Object o = "hello";
      Integer i = (Integer)o;
    } catch(ArithmeticException e) {
      System.out.println("除0错误");
    } catch(NullPointerException e) {
      System.out.println("空指针异常");
    } catch(Exception e) {
      // 打印异常的栈跟踪信息
      e.printStackTrace();
      System.out.println("未知异常");
    }
  }
}
package com.qfedu.exception;
public class App4 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    // 不管代码是否异常,最终都会执行finally代码块中逻辑
    // 在try或catch的代码块中,即使使用了return,finally代码块中的逻辑也会执行
    // 使用System.exit()情况下,退出整个程序,finally中逻辑不会执行
    try {
      int a = 10 / 3;
      System.out.println(a);
      // return;
      // 退出程序
      // System.exit(0);
    } catch (Exception e) {
      System.out.println(e.getMessage());
      return;
    } finally {
      System.out.println("finally");
    }
    // 了解
    // 语法上catch可以不写,如果不写,无法捕获异常,异常就会自动往上层抛,本例中,抛给jvm进行处理
    try {
      int b = 10 / 0;
    } finally {
      System.out.println("finally2");
    }
  }
}

抛出异常

声明方法时,通过throws指定抛出的异常

在方法中,通过throw抛出异常

package com.qfedu.throwes;
public class App {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    // main方法中调用test1() 方法,
    // test1()没有捕获异常并处理,当test1()发生异常时,将异常对象往上抛
    // 本例中,test1()中发生的异常抛给main()方法
    // main()中也没有捕获异常进行处理,main()方法将异常继续往上抛,最终抛给jvm,由jvm处理异常
    // test1();
    try {
      // test2();
      test3();
    } catch(ArithmeticException e) {
      System.out.println(e.getMessage());
    } catch(Exception e) {
      System.out.println("未知异常");
    }
  }
  public static void test1() {
    int a = 10 / 0;
    System.out.println(a);
  }
  // 在方法中,声明需要抛出的异常,针对受检异常相对多些
  public static void test2 () throws ArithmeticException {
//    int a = 10 / 0;
//    System.out.println(a);
    String str = null;
    System.out.println(str.length());
  }
  // 在方法中通过throw 抛出异常 ,针对自定义异常,针对需要改变运行流程的情况,使用相对多些
  public static void test3() {
    try {
      int a = 10 / 0;
    } catch(ArithmeticException e) {
      throw e;
    }
  }
}

自定义异常

继承Exception或者RuntimeException

一般结合throw一起使用,通过自定义异常,可以实现终止业务逻辑的功能

package com.qfedu.customerex;
// 如果继承Exception类,在其他地方创建并抛出异常类对象,默认会报错(当成受检异常进行处理)
// 个人建议,继承RuntimeException
public class LoginException extends RuntimeException{ 
  // 针对异常信息的编码值
  private int code;
  // 异常信息
  private String msg;
  public int getCode() {
    return code;
  }
  public void setCode(int code) {
    this.code = code;
  }
  public String getMsg() {
    return msg;
  }
  public void setMsg(String msg) {
    this.msg = msg;
  }
  public LoginException(int code, String msg) {
    super(msg);
    this.code = code;
    this.msg = msg;
  }
}
package com.qfedu.customerex;
public class App2 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {
      login(null, "1235");
      System.out.println("合法用户");
    } catch (LoginException e) {
//      System.out.println(e.getMsg());
      System.out.println(e.getMessage());
    }
  }
  // 借助抛异常的方式,终止程序的后续逻辑
  public static void login(String name, String password) {
    if(name == null || name.isEmpty()) {
      // 创建了一个自定义异常的对象,然后通过throw抛出
      throw new LoginException(101, "请输入用户名");
    }
    if(password == null || password.isEmpty()) {
      throw new LoginException(102, "请输入密码");
    }
    if(!(name.equals("admin") && password.equals("123"))) {
      throw new LoginException(103, "用户名或者密码错误");
    } 
  }
}
相关文章
|
6月前
|
C++
C++ 捕获所有异常并拿到错误原因的方法
C++ 捕获所有异常并拿到错误原因的方法
170 0
|
6月前
|
Java C++ Spring
解决NoUniqueBeanDefinitionException异常的方法
了解Spring框架中`NoUniqueBeanDefinitionException`异常的原因和解决方案。此异常发生在容器内有多个相同类型的bean时,Spring无法决定注入哪个bean。解决方法包括:使用`@Primary`注解标记首选bean,利用`@Qualifier`注解配合`@Autowired`、`@Resource`、`@Inject`或`@Value`指定bean名称。选择哪种方法取决于业务需求和具体场景,预防措施是避免创建多个同类型bean或使用`@Primary`注解。
228 0
|
6月前
|
SQL 安全 程序员
C++:异常
C++:异常
54 7
|
运维 编译器 C语言
异常(C++)
异常(C++)
68 1
|
6月前
|
Java 程序员 数据库连接
|
6月前
|
C语言 C++
C++异常
C++异常
49 0
|
6月前
|
程序员 编译器 Shell
C++『异常』
C++『异常』
63 0
|
存储 监控 Java
认识异常【超详细】
认识异常【超详细】
41 0
|
安全 Java 程序员