day_17 异常机制

本文详细介绍了Java中的异常处理机制,包括异常的产生原因、处理方式(throws和try...catch...)、异常类型的继承规则,以及finally块的使用。通过示例代码展示了如何妥善处理异常,如文件找不到、空指针等问题。此外,还提到了Java 7的自动关闭资源特性,并给出了用户登录场景的异常处理示例,强调了自定义异常类的创建及其在业务逻辑中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

day_17 异常机制

  • 异常发生的原因有很多,尤其是用户输入和要打开的资源不存在
  • 这些异常出错后,导致程序生命周期终止执行,从错误代码开始,之后的代码都不会执行
  • java中 有一个专门模拟异常的类,就是 Throwable , 所有异常都继承这个类
  • 异常处理的两种方式
  • throws : 抛出异常,告诉调用处,这里可能有什么问题
  • 如果你把异常抛给了调用处.那么调用处要么也抛出去,要么解决
  • try…catch… : 解决异常
  • try{
  • 高风险代码;
  • }catch(异常类型 变量){
  • 解决方案;
  • }
public class Exception_02 {

//抛出异常

//	public static void main(String[] args) throws FileNotFoundException {
	public static void main(String[] args)  {
		// 打开资源文件
		try {

//try...catch 解决异常FileInputStream fis = new FileInputStream("D:/xxx");System.out.println(123);
//		} catch (Exception e) {} catch (FileNotFoundException e) {// 打印错误的追踪栈帧,比较常用,适合程序员排错// e.printStackTrace();// 获取错误信息,适合响应给用户
			String msg = e.getMessage();
			System.out.println(msg);
		}
		System.out.println(456);
	}
}
当父类有异常且有子类继承时

子类抛出的异常只能包括父类或者比父类异常的子类

public class Exception_03 {

}
class A{
	public void m1() throws IOException{
		

	}
}
class B extends A{
	@Override
	// 方法覆写,不能比原方法拥有更宽泛的异常
	//  抛出的异常类,可以是父类方法中抛出的类,也可以是对应的子类 , 但是不能是它的父类
	// 父类抛出一个异常A , 那么子类 要么还抛出A , 要么抛出A的子类, 要么不抛异常 , 但是不能是A的父类
	public void m1() throws FileNotFoundException{
	}
}
  • try{
  •    高风险代码;
    
  • } catch(异常类型 变量){
  •    处理方案;
    
  • } catch(异常类型 变量){
  •    处理方案;
    
  • }…
  • catch中异常类型 不能有继承关系,如果有继承关系,需要从子类到父类
public class Exception_05 {
	public static void main(String[] args) {
//异常依次从子类到父类,因为多态性,如果父类在首位会接收到几乎所有异常,后面语句无法执行无法精确到异常的细节
		

		try {
			FileInputStream fileInputStream = new FileInputStream("");
		} catch (FileNotFoundException e) {
			System.out.println("找不到文件");
			// TODO: handle exception
		} catch (NullPointerException e) {
			System.out.println("不能为NULL");
		} catch (Exception e) {
	
			System.out.println("其他异常");
		}
	}

}
throws抛出异常并不会处理异常,是一种提醒机制
  • throws 抛出异常,并不会处理异常,是一种提醒机制
  • 如果你调用 的方法,抛出一个编译时异常,要么你就try…catch处理掉,要么你也抛出
  • throws 是抛出异常,并不会解决异常,一般用于类库端(被调用的这个类)
  • 而 try…catch… 是解决异常的,一般用于客户端(调用其他类的这个类,一般客户端都有main方法)
public class Exception_04 {
	public static void main(String[] args) {

//try...catch 解决文件找不到异常try {m1();} catch (FileNotFoundException e) {// TODO Auto-generated catch block
​			e.printStackTrace();}}public static void m1() throws FileNotFoundException{m2();}public static void m2()throws FileNotFoundException{m3();}public static void m3() throws FileNotFoundException{FileInputStream fis = new FileInputStream("xxx异常");}

}

当抛出多个异常时,逗号隔开没有先后顺序


public static void main(String[] args) throws Exception,
			FileNotFoundException, IOException {

	}

Finally
  • finally : 必须执行的语句块 比如 打开的资源,需要关闭

    finally 不能单独出现,必须和try一起使用 或者和 try…catch…一起使用

    finally语句块 只有一种不执行的情况,那就是关闭虚拟机 System.exit(0);

public class Exception_07 {
	public static void main(String[] args) {
		try {
			int a = 0;
			int b = 3;
			// 除数不能为0,会出错
			int c = b / a;
			System.out.println(c);
		} catch (Exception e) {
			e.printStackTrace();
			// 终止方法执行
			return;
			// System.exit(0);
		} finally {
			// 但是finally会执行
			System.out.println("2222");
		}
		// 执行不到,因为上面有return
		System.out.println("1111");
	}
}

执行结果为异常抛出,并输出2222,因为有return语句,程序终止1111不执行,但是finally会执行,

除非JVM虚拟机关闭

例题:

public class Exception_08 {
	public static void main(String[] args) {
		int result = m1();
		// 11
		System.out.println(result);
	}

	public static int m1() {
		int i = 10;
		try {
			// 因为finally中有return,并且优先级是比较高的
			// 所以在编译的时候 就把这里的return去掉了,只有i++
			 return i++;
//			i++;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 11
			System.out.println(i+"------------");
		
		}
		return i;
	}
}

finally优先级比try高。return语句执行finally中的,try语句的return i++,语句编译为i++.
自动关闭资源

/**

  • Java1.7新特性 自动关闭资源

  • try{

  •    开启资源;
    
  • }catch(异常类型 变量){

  •    处理措施;
    
  • }finally{

  •    关闭资源
    
  • }


  • try(开启资源){

  •    高风险代码;
    
  • }catch(异常类型 变量){

  •    处理措施;
    
  • }

public class Exception_10 {
public static void main(String[] args) {
//自动关闭资源
	try(FileInputStream fileInputStream = new FileInputStream("xxx");){
//		操作
	}catch (Exception e) {
	e.printStackTrace();
	}
}
}
  • 需求 完成用户登陆
  • 1 如果用户名不是admin 则提示用户名不存在
  • 2 如果密码不是root 则提示密码不正确
  • 客户端负责数据录入
  • service 负责 逻辑校验
客户端类Client
public class Client {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入用户名和密码 : ");
		String username = scanner.next();
		String password = scanner.next();
		
		try {
			UserService.login(username, password);
			System.out.println("登陆成功");
		} catch (UserException e) {
			// e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}
}

自定义异常类 UserException

/**
 * 1 继承一个已有的异常类
 * 			判断你应该是运行是异常还是编译时异常,如果是运行时异常需要继承 RuntimeException 否则就继承Exception即可
 * 			一般情况下 我们写的 一定是 编译时异常
 * 2 公共的无参构造
 * 3 公共的有参构造,传入字符串,并在构造方法中把该字符串传递给父类
 * 
 * @author 天亮教育-帅气多汁你泽哥
 * @Date 2021年10月20日 下午3:42:07
 */
 public class UserException extends Exception {
	public UserException() {

	}

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

逻辑实现类 UserService

package ThrowExample;

public class UserService {
	public static void login(String username,String password) throws UserException{
		if (username.equals("admin")) {
			if (password.equals("root")) {
				// TODO 登陆成功
				// return "登陆成功";
			}else {
				// TODO 密码不正确
				// return "密码不正确" ;
				throw new UserException("密码不正确");
			}
		}else{
			// TODO 用户名不正确
			// return "用户名不正确";
			throw new UserException("用户名不正确");
		}
	}
}
Test.java
package ThrowExample;

public class Test {
	public static void main(String[] args) throws UserException {
		// 异常源
		throw new UserException("xxxxxxxx");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值