异常处理的那些事——try catch finally、throw、throws\自定义异常
异常处理相信大家在之前的操作中都有遇见过,本文就异常总涉及到知识点做一总结。
文章目录
异常概述
运行时异常:程序在运行期间发生的错误。(非受查异常)
编译时异常:在编译时发生异常。(受查异常)
常见的异常类型
NullPointerException (空指针异常)
ArrayIndexOutOfBoundsException(数组角标越界异常)
NumberFormatException (类型转换异常)
ArithmeticException (算数异常)
当然异常的种类有很多在,上述只是列举出几种常见的异常
不处理异常
public static void main(String[] args){
String str = "lala";
System.out.println(str + "年龄是:");
int age = Integer.parseInt("20L");
System.out.println(age);
}
输出结果
lala年龄是:
Exception in thread "main" java.lang.NumberFormatException: For input string: "20L"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at Test.main(Test.java:15)
我们发现一旦出现异常, 程序就终止了. age 没有正确输出
捕获异常
Java中捕获异常的结构由try catch finally 3部分组成。
基本语法
try{
可能发生异常的程序
}catch(异常类型 异常对象){
处理异常
}
finally{
程序块
}
注:try语句块中的代码如何退出,都将执行finally语句!!!
示例 一:try catch后的执行过程
public static void main(String[] args) {
int[] arr = {1,2,3,4};
try{
System.out.println(arr);
System.out.println(arr[20]);
System.out.println("ok");
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
System.out.println("继续执行");
}
执行结果:
[I@16b98e56
继续执行
java.lang.ArrayIndexOutOfBoundsException: Index 20 out of bounds for length 4
at Test.main(Test.java:15)
从上边的栗子中可以看出,程序没有因为发生异常而停止执行,而是继续输出之后代码,try语句块中发生了数组角标越界,程序就会调转到catch语句中,并且执行,执行完catch语句中的代码,则继续执行之后的代码。
示例二:catch 只能处理对应种类的异常
public static void main(String[] args) {
int[] arr = {1,2,3,4};
try{
System.out.println(arr);
arr = null;
System.out.println(arr[20]);
System.out.println("ok");
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
}
输出结果:
[I@16b98e56
Exception in thread "main" java.lang.NullPointerException: Cannot load from int array because "arr" is null
at Test.main(Test.java:17)
此时,catch捕获不到刚才的异常,因为异常类型不匹配
示例三:catch可以有多个
public static void main(String[] args) {
int[] arr = {1,2,3,4};
try{
System.out.println(arr);
arr = null;
System.out.println(arr[20]);
System.out.println("ok");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("角标越界");
e.printStackTrace();
}catch (NullPointerException e){
System.out.println("空指针");
e.printStackTrace();
}
System.out.println("退出");
}
}
[I@16b98e56
空指针
退出
java.lang.NullPointerException: Cannot load from int array because "arr" is null
at Test.main(Test.java:17)
一段代码可能会抛出多种不同的异常, 不同的异常有不同的处理方式.。因此可以搭配多个 catch 代码块。
示例四:使用一个catch捕获所有异常
public static void main(String[] args) {
int[] arr = {1,2,3,4};
try{
System.out.println(arr);
arr = null;
System.out.println(arr[20]);
System.out.println("ok");
}catch(Exception e){
e.printStackTrace();
}
System.out.println("退出");
}
}
输出结果:
[I@16b98e56
退出
java.lang.NullPointerException: Cannot load from int array because "arr" is null
at Test.main(Test.java:17)
Exception是
try代码块传递给
catch代码块的变量类型,e是变量名。
catch代码块中的语句
e.printStackTrace()`是输出异常的类型、性质、栈层次以及出现在程序中的位置。获取异常的相关信息函数有以下3个:
- getMessage()函数:输出错误类型
- toString()函数:输出异常的类型与性质
- e.printStackTrace():输出异常的类型、性质、栈层次以及出现在程序中的位置
finally语句块
完整的异常处理一定包含finally语句,无论程序中是否有异常,finally语句块必然执行。
finally语句块不执行的特殊情况
- 在finally语句块中发生异常
- 在前面的代码中使用了System.exit()退出程序
- 程序所在的线程死亡
- 关闭CPU
自定义异常、throw、throws
在程序中使用自定义异常类,可以分为以下几个步骤:
- 创建自定义类
- 在方法中通过throw关键字抛出异常对象
- 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句块执行并处理,否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常
- 在出现异常方法调用者中捕获并处理异常
自定义异常通常会继承 Exception 或者 RuntimeException
简单栗子:
实现一个简单的控制台版用户登陆程序, 程序启动提示用户输入用户名密码. 如果用户名密码出错, 使用自定义异常的方式来处理
package Error;
import java.util.Scanner;
class UserError extends Exception{
public UserError(String message){
super(message);
}
}
class PassWordErroe extends Exception{
public PassWordErroe(String message){
super(message);
}
}
public class MyError {
private static String username= "adime";
private static String password = "123";
public static void register(String username, String password) throws UserError,PassWordErroe{
if(!MyError.username.equals(username)){
throw new UserError("用户名错误");
}
if(!MyError.password.equals(password)){
throw new PassWordErroe("密码错误");
}
System.out.println("登录成功");
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名");
String user = scanner.nextLine();
System.out.println("请输入密码");
String poss = scanner.nextLine();
try{
register(user,poss);
}catch (UserError e){
e.printStackTrace();
}catch (PassWordErroe e){
e.printStackTrace();
}
}
}
一个栗子中涉及到以下知识点:
1、throw关键字抛出异常:
throw关键字常用于方法体中,并且抛出一个异常对象。程序执行到throw语句时终止,后边的语句都不执行。
2、throws关键字抛出异常:
throws关键字通常声明在应用方法时,用来指定方法可能抛出的异常,多个可以使用逗号隔开。
throws将异常抛给上级后,如果不想处理异常,可以继续向上抛,但最终要有处理异常的代码
推荐阅读
-
C#异常处理中try和catch语句及finally语句的用法示例
-
C++中的try throw catch 异常处理
-
异常类的了解、异常的处理方案、编译时期异常和运行时期异常区别、throws和throw的区别、自定义异常类 、捕获异常的标准格式、final、finally、finalize的区别
-
try catch和Throws处理异常的区别
-
Java编程中异常处理 try-catch-finally语句的一些分析
-
try、catch、finally详解,你不知道的异常处理
-
C#异常处理中try和catch语句及finally语句的用法示例
-
C++中的try throw catch 异常处理
-
异常的使用,try-catch-finally的使用,自定义异常,throws和throw的区别
-
13异常(try/catch/finally/throws/throw、自定义异常、面试题:return执行顺序)