JAVA--异常机制

1.之前碰到的异常

1 数组中 下标越界异常

2 对象中 空指针异常

3 递归中 栈内存溢出

4 多态中 类型转换异常

2.是什么

异常就是错误的一种描述

异常是java中专门响应错误的一种机制,能够有效的处理异常,并使得异常成为程序中的一部分,能够更有力的增强程序鲁棒性更易于调试

发生异常的原因有很多

1 用户输入了非法数据

2 要找的文件不存在

3 网络通信中断

4 JVM溢出

出现错误后,会终止程序生命周期执行,此时引入异常后,能够保证程序不会终止,并且还能够把错误信息,进行描述反馈

3.继承体系

 4.Error

主要描述的是一些系统内部错误,比如我们之前碰到的栈内存溢出  OOM(内存溢出)

 5.Exception

5.1 是什么

一般我们会把exception作为所有异常类的父类, 而exception又分为两大类

RuntimeException 和 非RuntimeException 运行时异常和非运行时异常(编译时异常)

运行时异常,一般是由于程序员粗心导致,比如空指针,比如 下标越界, 程序员完全可以通过if判断来解决这个问题

但是编译时异常,一般需要我们重点学习,另外编译时异常是我们在编码中就需要处理的,如果不处理,不能运行

5.2常用方法

public static void main(String[] args) {
		try {
			int a = 1;
			int b = 0;
			int c = a / b;
		} catch (Exception e) {
			// 获取错误信息 并打印 / by zero  一般用于响应给客户看
			System.out.println(e.getMessage());
			// 打印追踪栈帧  一般用于 给程序员看,方便解决错误和问题
			e.printStackTrace();
		}
		System.out.println("====");
	}

5.3Try

5.3.1 第一种用法

public static void main(String[] args) {
		int a = 10;
		int b = 0;
		// 大部分运行时异常,都可以通过if来解决
		// 但是if只能处理可以预知的错误
		if (b == 0) {
			System.out.println("除数不能为0");
		} else {
			int c = a / b;
			System.out.println(c);
		}

		System.out.println("========");
	}

//==================================================================
public static void main(String[] args) {
		int a = 10;
		int b = 0;

		try {
			// 高风险代码
			int c = a / b;
			System.out.println(c);
			// 如果以上代码没有出现问题,则try会正常执行完成
			// 就不会执行catch
		} catch (Exception e) {
			// 如果try中代码出现异常,则直接执行catch
			System.out.println("除数不能为0");
		}
		System.out.println("====");
	}

5.3.2 第二种用法

/**
try{
高风险代码
}catch(异常类型 变量){
处理方案
}catch(异常类型 变量){
处理方案
}
可以写多个catch 处理不同的异常
catch从上往下,要么异常类型没有继承关系,要么异常类型必须是由子到父
*/
public static void main(String[] args) {

		try {
			// 打开指定文件 传入文件路径
			FileInputStream fis = new FileInputStream("xxx");
			String s = null;
			s.trim();
		} catch (FileNotFoundException e) {
			System.out.println("文件不存在");
		} catch (NullPointerException e) {
			System.out.println("变量不能为空");
		}
	}

5.3.3 第三种用法

/**
* try{ 
* 			高风险代码 
* }catch(异常类型  | 异常类型 变量...){
* 
* } 
* 
* 可以同时捕捉多个异常,进行相同的处理措施
* 
* 并且多个异常之间,不能有继承关系,如果有继承关系则直接写父类即可
*/
public static void main(String[] args) {

		try {
			// 打开指定文件 传入文件路径
			FileInputStream fis = new FileInputStream("xxx");
			String s = null;
			s.trim();
		} catch (FileNotFoundException  | NullPointerException e2) {
			System.out.println("出错了");
		} 
	}

5.3.4 第四种用法


/**
 * Java7开始,有两个改进
 * 
 * 1 一个catch中 可以通过 | 捕捉多个异常
 * 
 * 2 可以自动关闭资源
 * 
 * try( 打开资源语句 ){ 
 * }catch(异常类型 变量){
 * }
 * 
 * 传统写法是 try{ }catch(异常类型 变量){ }finally{ }
*/
public static void main(String[] args) {

		try (FileInputStream fis = new FileInputStream("E:/a.txt");) {
			// 打开资源
			// 读取文件中内容
			System.out.println(fis.read());

		} catch (Exception e) {
			// e.printStackTrace();
			System.out.println("找不到文件");
		}
	}

5.4 Throws

5.4.1 第一种用法

/**
 * throws 抛出异常,把问题抛出去,并没有解决
 * 
 * 提醒调用处,这里可能出现问题,你处理一下
 * 
 * 服务端(被调用出),一般使用throws抛出异常,因为不知道如何解决,所以把问题抛给调用处
 * 
 * 客户端(调用处),一般使用try进行异常处理,因为只有调用处才知道,出问题应该如何处理
*/
public static void main(String[] args) {
		try {
			m1();
		} catch (FileNotFoundException e) {
			// e.printStackTrace();
			System.out.println(e.getMessage());
		}
		System.out.println("=======");
	}

	public static void m1() throws FileNotFoundException {
		m2();
	}

	public static void m2() throws FileNotFoundException {
		m3();
	}

	public static void m3() throws FileNotFoundException {
		new FileInputStream("sss");
	}

5.4.2 第二种用法

 // throws 抛异常,可以同时抛出多个
 //多个用逗号隔开,并且多个异常中不用考虑继承和顺序
public static void main(String[] args) throws FileNotFoundException,
			NullPointerException, Exception, RuntimeException {

	}

5.4.3 注意--方法覆写

不能比原方法拥有更宽泛的异常

子类覆写的方法,可以不抛出异常

要么和父类方法抛出的异常一样

要么是父类方法抛出异常类的子类

要么不抛出,把异常处理

不能是父类方法抛出异常类的父类

5.5 Finally

5.5.1是什么

finally 是必须执行的语句块,写在finally中的代码,一定会执行
只有一种情况不会执行,就是 System.exit(0) 退出JVM虚拟机
因为其执行的特征,所以一般用于关闭资源操作
不能单独使用,需要结合try 或者 try..catch..一起使用

5.5.2 怎么用

public static void main(String[] args) {
		// 1
		try {
		} finally {
		}
		// 2
		try {
			// System.exit(0) ;
			// 这里会报错, 除数不能为0
			System.out.println(10 / 0);
			// 所以这里的代码执行不到
			System.out.println("=====try");
		} catch (Exception e) {
			// 因为出错,所以执行catch
			System.out.println("----catch");
			// 终止方法执行
			return;
		} finally {
			// 这里依然执行,因为 finally必须执行,所以finally优先级大于return
			System.out.println("-----finally");
		}
		// 因为catch中有return, 所以这里不执行
		System.out.println("=========");
	}

5.5.3 注意事项

不能单独使用

除了关闭虚拟机以外,finally一定会执行

5.5.4 应用案例

public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			// 打开资源
			fis = new FileInputStream("E:/a.txt");
			// 读取文件中内容
			System.out.println(fis.read());

		} catch (Exception e) {
			// e.printStackTrace();
			System.out.println("找不到文件");
		} finally {
			// 关闭资源
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

5.6 Throw

异常源点,创建一个异常

throw new 异常类( 错误信息 );

public static void main(String[] args) {
		try {
			m1();
		} catch (FileNotFoundException e) {
			// 自己抛出的异常
			System.out.println(e.getMessage());
			// 异常追踪栈帧
			e.printStackTrace();
		}
	}

	public static void m1() throws FileNotFoundException  {
		// 创建一个异常 , 一般需要结合throws 抛出
		// throw 会终止方法执行
		throw new FileNotFoundException("自己抛出的异常");
	}

5.7 自定义异常类

5.7.1 定义语法

1 继承一个已有的异常类
如果是运行时异常,一般继承RuntimeException
如果是编译时异常,一般继承Exception
但是我们自定义的一般是编译时异常 所以直接继承Exception即可
2 提供无参构造
3 提供有参构造,用于传递错误信息,并把错误信息传递给父类构造

public StudentException() {
	}

	public StudentException(String mgs) {
		super(mgs);
	}

5.7.2 应用场景

比如,写一个用户管理模块

5.7.2.1 用户类
package com.ThrowExample.model;

public class User {
	private String username;
	private String password;
	private String nickname;

	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 String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

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

	public User() {
		super();
	}

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

}
5.7.2.2 Controller
package com.ThrowExample.controller;

import java.util.Scanner;

import com.ThrowExample.model.User;
import com.ThrowExample.service.UserService;
import com.ThrowExample.util.UserException;

// 前端交互,接收用户输入
public class UserController {
	public static void main(String[] args) {
		// 获取用户输入
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入用户名 : ");
		String username = scanner.next();
		System.out.println("请输入密码 : ");
		String password = scanner.next();
		// 封装User对象
		User user = new User(username, password);
		// 传入进行登陆校验
		UserService userService = new UserService();
		try {
			User loginUser = userService.login(user);
			System.out.println("登陆成功...正在跳转主页");
		} catch (UserException e) {
			// 获取错误信息
			System.out.println(e.getMessage());
		}
	}
}
5.7.2.3 Service
package com.ThrowExample.service;

import com.ThrowExample.dao.UserDao;
import com.ThrowExample.model.User;
import com.ThrowExample.util.UserException;

// 业务逻辑处理
public class UserService {
	public User login(User user) throws UserException{
		// 1 用户输入的信息 user
		// 2 根据用户名获取用户信息
		UserDao userDao = new UserDao();
		User oldUser = userDao.loadByUsername(user.getUsername());
		// 3 校验
		if (oldUser == null) {
			throw new UserException("用户名不存在");
		}
		if (!user.getPassword().equals(oldUser.getPassword())) {
			throw new UserException("密码不正确");
		}
		// 登陆成功,返回用户信息
		return oldUser;
	}
}
5.7.2.4 Dao
package com.ThrowExample.dao;

import com.ThrowExample.model.User;

// 数据库操作
public class UserDao {
	// 需求 : 根据用户名获取用户信息
	public User loadByUsername(String username) {
		if (username.equals("admin")) {
			User user = new User("admin", "root", "管理员");
			return user;
		}
		return null;
	}
}
5.7.2.5异常类
package com.ThrowExample.util;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值