异常

异常机制

1. 之前常见的运行时异常

1 空指针异常
2 下标越界
3 类型转换
4 栈内存移出

异常概述

异常是Java中提供的一种识别及响应错误情况的一致性机制。有效地异常处理能使程序更加健壮、易于调试。
异常发生的原因有很多,比如:
1)用户输入了非法数据
2)要打开的文件不存在
3)网络通信时连接中断
4)JVM内存溢出
5)这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。

  • 如果程序报错,会终止程序生命周期执行(错误代码之后的代码都不会执行了)
  • 1 异常机制
  •  异常就是错误的另一种说法
    
  •  在java中有一个专门模拟所有异常和错误的类(Throwable),所有的异常类都必须继承这个类
    
  • 异常是我们程序员在写程序的时候,对某些高风险代码的操作规定了一个提醒机制,对于系统来说 就是处理异常的触发机制
  • 2 异常机制的处理形式
  •  	try...catch... : 解决异常,一般用在客户端
    
  •  	throws : 抛出异常,一般用在类库端(服务端)
    
  •  	throw : 制造异常,异常源点,创建一个异常对象
    
  • 用if…else…进行判断,也可以把大多数错误屏蔽掉,但是 只能处理我们预知的情况,对于无法预知的情况,就需要使用try…catch…解决了
  • 3 不同异常机制的选择
  •  	有些错误我们不想处理,或者没有办法处理,或者不知道应该怎么处理(通常是类库端),一般使用throws把问题抛给调用处
    
  •  	在一个就是知道怎么处理,直接使用try...catch...处理问题即可,一般是main方法
    
  • 4 finally语句块
  •  	必须执行的语句块
    
  • 5 异常机制的继承体系
  •  最大的异常类是 Throwable
    
  •  	直接两个子类 : Error(我们解决不了,比如栈溢出)和  Exception(所有的子类除了一个RunTimeException之外,其他全是编译时异常)
    
  • 6 语法 :
  •  try{
    
  •  	高风险代码;
    
  •  }catch(异常类 变量){
    
  •  	处理措施;
    
  •  }
    

目的 : 增强程序的鲁棒性,健壮性

异常继承体系

在这里插入图片描述

4. Error

  1. 概念
    系统内部错误,这类错误由系统进行处理,程序本身无需捕获处理。
    比如:OOM(内存溢出错误)、VirtualMachineError(虚拟机错误)、StackOverflowError(堆栈溢出错误)等,一般发生这种情况,JVM会选择终止程序。
  2. 示例
    //堆栈溢出错误
    public class TestError {
    public static void recursionMethod() {
    recursionMethod();// 无限递归下去
    }
    public static void main(String[] args) {
    recursionMethod();
    }
    }

报错信息:
Exception in thread “main” java.lang.StackOverflowError
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)
at com.TestError.recursionMethod(TestError.java:5)

5. Exception

5.1概述

Exception是所有异常类的父类。分为非RuntimeException和RuntimeException 。
非RuntimeException
指程序编译时需要捕获或处理的异常,如IOException、自定义异常等。属于checked异常。
RuntimeException
指程序编译时不需要捕获或处理的异常,如:NullPointerException等。属于unchecked异常。一般是由程序员粗心导致的。如空指针异常、数组越界、类型转换异常等。

如果程序报错,会终止程序生命周期执行(错误代码之后的代码都不会执行了)
1 异常机制
异常就是错误的另一种说法
在java中有一个专门模拟所有异常和错误的类(Throwable),所有的异常类都必须继承这个类
异常是我们程序员在写程序的时候,对某些高风险代码的操作规定了一个提醒机制,对于系统来说 就是处理异常的触发机制
2 异常机制的处理形式
try…catch… : 解决异常,一般用在客户端
throws : 抛出异常,一般用在类库端(服务端)
throw : 制造异常,异常源点,创建一个异常对象
用if…else…进行判断,也可以把大多数错误屏蔽掉,但是 只能处理我们预知的情况,
对于无法预知的情况,就需要使用try…catch…解决了
3 不同异常机制的选择
有些错误我们不想处理,或者没有办法处理,或者不知道应该怎么处理(通常是类库端),一般使用throws把问题在一个就是知道怎么处理,直接使用try…catch…处理问题即可,一般是main方法
4 finally语句块
必须执行的语句块
5 异常机制的继承体系
最大的异常类是 Throwable
直接两个子类 : Error(我们解决不了,比如栈溢出)和 Exception(所有的子类除了一个RunTimeException之外,其他全是编译时异常)

  • 6 语法 :
  • try{
  •  	高风险代码;
    
  •  }catch(异常类 变量){
    
  •  	处理措施;
    
  •  }
    

5.2 常用方法

在这里插入图片描述
在这里插入图片描述

5.3 TryCatch

5.3.1 第一种

在这里插入图片描述
在这里插入图片描述

这种就是编译时异常,如果不出来,压根不能运行,这时候 我们要么抛出,要么处理

5.3.2 第二种

  • try{
  •  高风险代码;
    
  • }catch(异常类 变量){
  •  异常操作
    
  • }catch(异常类 变量){
  •  异常操作
    
  • }
  • 1 catch语句可以根据代码返回的异常编写多个
  • 2 但是从上往下,必须是子类到父类,要不然会因为多态的原因,父类会把子类对象捕捉
  • 3 从上往下可以是没有继承关系的,那样就不需要考虑顺序问题
  • 4 多个异常,只会有一个执行,因为最先出错的语句之后,try中的代码就不再执行了
  • 如果 多个异常中,我们的处理措施是一样的,可以直接写exception 没问题
  • 但是 如果操作不同,就不能使用exception捕捉
  •  	比如 用户登陆,如果使用exception捕捉,你是不知道是用户名不对还是密码不对的,那么就只能提醒 "用户名或密码不对"
    
  •  	如果想分开提醒 到底是用户名错了还是密码错了 就只能分开捕捉
    

在这里插入图片描述

5.3.3 第三种

  • java1.7开始,出现了一个新的写法,可以一次catch捕捉多个异常,
  • 但是异常之间不能有继承关系,如果有继承关系,之间写父类
  • 多个异常使用 | 隔开
  • 异常类型 | 异常类型 | …

在这里插入图片描述

5.3.4 第四种

  • java1.7 异常有两个改进
  •  1 多个异常可以在一个catch中同时捕捉, 需要使用 | 隔开
    
  •  2 自动关闭资源
    
  •  	try(开启资源语句){
    
  •  		高风险代码;
    
  •  	}catch(异常类 变量){
    
  •  		处理语句;
    
  •  	}
    

在这里插入图片描述

5.4 Throws

5.4.1 第一种

  • throws 并不会把异常处理,而是一种提醒,告诉调用人员,这里有个异常/可能有个异常没有解决,你注意一下
  • 如果你调用的方法 通过 throws 提醒了你,要么你也提醒调用你的地方,或者你 try 处理掉
    在这里插入图片描述

5.4.2 第二种

  • throws 也可以同时抛出多个异常,使用 逗号 隔开
  • 因为 throws 只是一个提醒,所以无所谓顺序和继承关系
    在这里插入图片描述

5.4.3 注意-覆写不能有更宽泛的异常

  • 子类中重写的方法,不能比父类有更宽泛的异常
  • 也就是说,子类方法中抛出的异常,必须是父类方法抛出的异常类,或者是其子类
  • 子类覆写后 异常 <= 父类 方法的异常
    在这里插入图片描述

5.5 Finally

5.5.1 基本使用

finally : 必须执行的语句块

我们在编程当中,会碰到程序出错的情况,但是某些情况下,尽管出错了,某些代码也仍然需要让他执行

比如关闭资源语句

1 finally 可以直接和 try… finally{} 一起使用
2 finally 不能单独使用
3 也可以和try…catch…finally… 一起使用
4 只有一种不执行 的情况
System.exit() : 关闭虚拟机

在这里插入图片描述

5.5.2 注意事项(return)

在这里插入图片描述

5.5.3 面试题

谈谈你对final的理解
1 final是什么,怎么用
2 finally是什么,怎么用
3 finalize是什么,怎么用

5.5.4 Finally一个应用场景

在这里插入图片描述

5.6 Throw

异常源点,创建一个异常
throw new 异常类( 错误信息 );

详细用法参考 自定义异常

异常源点,创建一个异常
throw new 异常类( 错误信息 );

详细用法参考 自定义异常

6. 自定义异常类

6.1 定义异常类

1 继承一个 已有的异常类,基本上就继承Exception即可,如果是运行时异常 就继承RuntimeException

2 无参构造

3 有参构造,传入错误信息,并把信息传递给父类 super(xxx)
在这里插入图片描述

6.2 应用场景

需求 : 完成用户登陆

1 如果用户名不是 admin  则 提示 用户名不存在
2 如果密码不是 root 则 提示 密码不正确

使用自定义异常类 做提示

/**

  • 自定义异常类
  • 1 继承一个 已有的异常类,基本上就继承Exception即可,如果是运行时异常 就继承RuntimeException
  • 2 无参构造
  • 3 有参构造,传入错误信息,并把信息传递给父类 super(xxx)

*/
public class UserException extends Exception {
public UserException() {

}

public UserException(String msg) {
	super(msg);
}

}

6.2.1 用户类
public class User {
private String username;
private String password;

public String getUsername() {
	return username;
}

public void setUsername(String username) {
	this.username = username;
}

public String getPassword() {
	return password;
}

public void setPassword(String password) {
	this.password = password;
}

public User(String username, String password) {
	super();
	this.username = username;
	this.password = password;
}

public User() {
	super();
}

6.2.2 业务类
package ThrowExample;

/**

  • 需求 : 完成用户登陆
  • 1 如果用户名不是 admin 则 提示 用户名不存在 2 如果密码不是 root 则 提示 密码不正确
  • 使用自定义异常类 做提示

*/
public class UserService {
public void login(User user) throws UserException {
if (“admin”.equals(user.getUsername())) {
// 如果用户名是admin 就比较密码
if (“root”.equals(user.getPassword())) {
System.out.println(“登陆成功”);
} else {
// 如果密码不正确 就抛异常 提示密码不正确
throw new UserException(“密码不正确”);
}
} else {
// 如果用户名不存在 就抛异常 提示用户名不存在
throw new UserException(“用户名不存在”);
}
}
}

6.2.3 客户端类

package ThrowExample;

import java.util.Scanner;

/**

  • 客户端

*/
public class Client {

public static void main(String[] args) {
	System.out.println("请输入用户名和密码 : ");
	Scanner scanner = new Scanner(System.in);
	// 获取用户输入
	String username = scanner.next();
	String password = scanner.next();
	
	// 封装为用户类对象
	User user = new User(username, password);
	
	// 创建业务类对象
	UserService userService = new UserService();
	// 登陆
	try {
		userService.login(user);
		System.out.println("跳转到主页");
	} catch (UserException e) {
		// 打印追踪栈帧,没有必要了,只需要把错误提醒的信息 展示给页面即可
		// 因为这里 有错 才是对的,所以这个追踪栈帧对程序员来说 没有任何价值
		e.printStackTrace();
		
		// 获取错误信息
		String msg = e.getMessage();
		// 传递到页面
		System.out.println(msg);
	}
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值