zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Java学习笔记 (异常相关知识)

JAVA笔记异常学习 知识 相关
2023-06-13 09:18:56 时间
异常的分类

在程序开发中,异常指不期而至的各种状况。它是一个事件,当发生在程序运行期间,会干扰正常的指令流程。在Java中,通过Throwable及其子类描述各种不同的异常类型,Throwable有Exception和Error两个重要的子类。

Error

Error是程序无法处理的错误, 表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关, 而表示代码运行时JVM ( Java虚拟机) 出现的问题。例如, Java 虚拟机运行错误( VirtuaI MachineError ) ,当JVM 不 再有继续执行操作所需的内存资源时, 将出现OutOfMemoryError。这些错误是不可查的, 因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说, 即使确实发生了错误, 本质上也不应 该试图去处理它所引起的异常状况。因此我们编写程序时不需要关心这类异常。

Exception

Exception 是程序本身可以处理的异常。异常处理通常指针对这种类型异常的处理。Exception 类的异常包括checked exception 和unchecked exception。

unchecked exception:
  • unchecked exception : 编译器不要求强制处置的异常。
  • 包含RuntimeException 类及其子类异常。
  • 如NuIIPointerException( 空指针异常) 、 Index Out Of Bounds Exception( 下标越界异常) 等, 这些异常是unchecked exception。
  • Java 编译器不会检查这些异常, 在程序中可以选择捕获处理, 也可以不处理, 照样正常编译通过。
checked exception:

Java 编译器会检查这些异常, 当程序中可能出现这类异常时, 要求必须进行异常处理, 否则编译不会通过。

异常处理

在Java应用程序中,异常处理机制为:抛出异常、捕捉异常

抛出异常

  • 当一个方法出现错误引发异常时, 方法创建异常对象并交付运行时系统。
  • 异常对象中包含了异常类型和异常出现时的程序状态等异常信息。
  • 运行时系统负责寻找处置异常的代码并执行。

捕获异常

  • 在方法抛出异常之后, 运行时系统将转为寻找合适的异常处理器。
  • 运行时系统从发生异常的方法开始, 依次回查调用栈中的方法, 当异常处理器所能处理的异常类型与方法抛出的异常类型相符时, 即为合适的异常处理器。
  • 当运行时系统遍历调用栈而未找到合适的异常处理器, 则运行时系统终止。同时, 意味着Java 程序的终止。
  • 对于运行时异常、错误或可查异常, Java 技术所要求的异常处理方式有所不同。
  • 总体来说, Java规定: 对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeException 和Error。
  • 简单地说, 异常总是先被抛出, 后被捕捉的。
try-catch-finally
import java.util.InputMismatchException;
import java.util.Scanner;

public class TryDemoOne {

	public static void main(String[] args) {
	/*	// 要求:定义两个整数,输出两数之商
		
		int one=12;
		int two=2;
		System.out.println("one和two的商是:"+ (one/two));
    */
		
		// 要求:定义两个整数,接受用户的键盘输入,输出两数之商
		Scanner input=new Scanner(System.in);
		System.out.println("=====运算开始=====");
		try{
			System.out.print("请输入第一个整数:");
			int one=input.nextInt();
			System.out.print("请输入第二个整数:");
			int two=input.nextInt();
			System.out.println("one和two的商是:"+ (one/two));
		}catch(ArithmeticException e){
			System.exit(1);//终止程序运行
			System.out.println("除数不允许为零");
			e.printStackTrace();
		}catch(InputMismatchException e){
			System.out.println("请输入整数");
			e.printStackTrace();
		}catch(Exception e){
			System.out.println("出错啦~~");
			e.printStackTrace();
		}finally{
			System.out.println("=====运算结束=====");
		}
	}

}

使用规则:

  • 语法组合: try-catch try-finally try-catch-finally try-catch-catch-catch…-catch-finally
  • try 块后可以接零个或多个catch 块如果没有catch, 则必须跟一个finally 块。不管是否发生异常都会执行finally块(除非中断程序,如System.exit(1))。
  • 一旦某个catch 捕获到匹配的异常类型, 将进入异常处理代码。一经处理结束, 就意味着整个try-catch 语句结束。其他的catch子句不再有匹配和捕获异常类型的机会。
  • 对于有多个catch 子句的异常程序而言, 应该尽量将捕获底层异常类的catch子句放在前面, 同时尽量将捕获相对高层的异常类的catch 子句放在后面。否则, 捕获底层异常类的catch子句将可能会被屏蔽。 常见的异常类型:

使用的经验总结:

  • 处理运行时异常时, 采用逻辑去合理规避同时辅助try-catch处理
  • 在多重catch 块后面,可以加一个catch (Exception) 来处理可能会被遗漏的异常
  • 对于不确定的代码, 也可以加上try-catch , 处理潜在的异常
  • 尽量去处理异常, 切忌只是简单的调用printStackTrace()去打印输出
  • 具体如何处理异常, 要根据不同的业务需求和异常类型去决定
  • 尽量添加finally语句块去释放占用的资源
throw、throws
  • 可以通过throws声明将要抛出何种类型的异常,通过throw将产生的异常抛出。
  • throw 用来抛出一个异常。 例如:throw new IOException(); throw 抛出的只能够是可抛出类ThrowabIe 或者其子类的实例对象。 例如: throw new String( “ 出错啦" ); 是错误的
  • 如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。
  • 例如:汽车在运行时可能会出现故障,汽车本身没办法处理这个故障,那就让开车的人来处理。
public void method() throws Exception1,Exception2{
}
  • 当方法抛出异常列表中的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理。

throws的使用规则 1 、如果是不可查异常( unchecked exception ) 即Error 、RuntimeException 或它们的子类, 那么可以不使用throws 关键字来声明要抛出的异常, 编译仍能顺利通过, 但在运行时会被系统抛出。 2 、如果一个方法中可能出现可查异常, 要么用try-catch 语句捕获,要么用throws 子句声明将它抛出,否则会导致编译错误 3 、当抛出了异常, 则该方法的调用者必须处理或者重新抛出该异常。 4 、当子类重写父类抛出异常的方法时, 声明的异常必须是父类方法所声明异常的同类或子类。

package com.imooc.test;

import java.util.Scanner;

public class TryDemoFour {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			testAge();
		} catch (HotelAgeException e) {
			System.out.println(e.getMessage());
			System.out.println("酒店前台工作人员不允许办理入住登记");
		}catch(Exception e){
			e.printStackTrace();
		}
	}


	public static void testAge() throws HotelAgeException {
		System.out.println("请输入年龄:");
		Scanner input = new Scanner(System.in);
		int age = input.nextInt();
		if (age < 18 || age > 80) {
			//throw new ArithmeticException();
			//throw new Exception("18岁以下,80岁以上的住客必须由亲友陪同");
			throw new HotelAgeException();
		} else {
			System.out.println("欢迎入住本酒店");
		}
	}
}
public class HotelAgeException extends Exception {
	public HotelAgeException(){
		super("18岁以下,80岁以上的住客必须由亲友陪同");
	}
}