Java异常

异常

异常:程序在运行过程中出现的特殊情况。

必要性:

任何程序都可能存在大量的未知问题、错误。

如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失。

一、异常

1.1异常分类

异常分类图:
在这里插入图片描述
Throwable:可抛出的,一切异常或错误的父类,位于java.lang包中

Error:JVM、硬件、执行逻辑错误,不能手动抛出。常见:StackOverflowError、OutOfMemoryError等

Exception:程序在运行和配置中产生的问题,可处理

一般性异常( CheckedException ):检查时异常,必须处理

RuntimeException:运行时异常,可处理,可不处理

常见运行时异常:

异常描述
NullPointerException空指针异常
ArrayIndexOutOfBoundsException数组越界异常
ClassCastException类型转换异常
NumberFormatException数字格式化异常
ArithmeticException算术异常

1.1.1异常的产生

  • 自动抛出异常:当程序在运行时遇到不符合规范的代码或结果时,会产生异常。
  • 手动抛出异常:语法:throw new 异常类型(“实际参数”)。
  • 产生异常结果:相当于遇到 return语句,导致程序因异常而终止。

1.1.2异常传递

  • 异常的传递:

    按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。

  • 受查异常:throws 声明异常,修饰在方法参数列表后端。

  • 运行时异常:因可处理可不处理,无需声明异常。

1.2异常处理

Java的异常处理是通过5个关键字来实现的:

  • try:执行可能产生异常的代码 。
  • catch:捕获异常 ,并处理。
  • finally:无论是否发生异常,代码总能执行。
  • throw: 手动抛出异常 。
  • throws:声明方法可能要抛出的各种异常。

1.2.1try-catch-finally

语法:

try…catch:

try {

​ //可能出现异常的代码

} catch(Exception e) {

​ //异常处理的相关代码,如:getMessage()、printStackTrace()

}


try…catch…finally:

try {
//可能出现异常的代码
} catch(Exception e) {

​ //异常处理的相关代码,如:getMessage()、printStackTrace()

} finally{
//是否发生异常都会执行,可以释放资源等。
}

关闭资源

​ return :是结束当前方法----应该要资源释放了

​ System.exit(0):退出虚拟机所有的资源回收,没必要在执行finally


多重catch:

try{

​ //可能出现异常的代码。

}catch(异常类型1){

​ //满足异常类型1执行的相关代码。

}catch(异常类型2){

​ //满足异常类型2执行的相关代码。

}catch(异常类型3){

​ //满足异常类型3执行的相关代码

}

(多重catch,遵循从子( 小 )到父( 大 )的顺序,父类异常在最后。)


try…finally…不能捕获异常 ,仅仅用来当发生异常时,用来释放资源。

一般用在底层代码,只释放资源不做异常处理,把异常向上抛出。

语法:

try{
//可能出现异常的代码

}finally{

//是否发生异常都会执行,可以释放资源等}

示例:

public class TestTry {
	public static void main(String[] args) {
		try {
			Scanner input = new Scanner(System.in);
			System.out.println("请输入一个整数:");
			int num1 = input.nextInt();
			System.out.println("请输入除数");
			int num2 = input.nextInt();
			System.out.println(num1 + "/" + num2 + "=" + num1/num2);
		}catch (InputMismatchException e) {
			System.out.println("输入不为整数");
			return;
		}catch (ArithmeticException e) {
			System.out.println("除数不能为0");
			System.exit(0);
		} catch (Exception e) {
			System.out.println("其它异常");
		}finally {
			System.out.println("有没有异常都会执行,return也会输出,System.exit()不会输出");
		}
	}
}

1.3声明抛出异常

Java程序在执行过程中如果出现异常,会自动生成一个异常类对象,该异常对象将被自动提交给JVM, 这个过程称为抛出**(throw)**异常。

1.3.1声明异常

在一个方法体中抛出了异常,使用throws通知调用者,让调用者去处理这个异常

public class TestThrow {
	public static void main(String[] args) {	
		try {
			divide(); // 调用者处理异常
		}catch (InputMismatchException e) {
			System.out.println("输入不为整数");
			return;
		}catch (ArithmeticException e) {
			System.out.println("除数不能为0");
			System.exit(0);
		} catch (Exception e) {
			System.out.println("其它异常");
		}finally {
			System.out.println("有没有异常都会执行,return也会输出,System.exit()不会输出");
		}
	}
	// 声明一个异常 , 调用者去处理
	public static void divide() throws Exception{		
		Scanner input = new Scanner(System.in);
		System.out.println("请输入一个整数:");
		int num1 = input.nextInt();
		System.out.println("请输入除数");
		int num2 = input.nextInt();
		System.out.println(num1 + "/" + num2 + "=" + num1/num2);
	}
}

1.3.2抛出异常

自行抛出的异常

关键字:throw

建议抛出自定义异常,因为这是有语义,便于错误定位

public class TestThrow {
	String name;
	char gender;
	int age;
	public TestThrow(String name, char gender, int age) {
		super();
		this.name = name;
		this.gender = gender;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public char getGender() {
		return gender;
	}
	public void setGender(char gender) {
		if ((gender+"").equals("男")||(gender+"").equals("女")) {
			this.gender = gender;
		}else {
			throw new RuntimeException("性别不符合异常");
		}
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		if (age >=0 && age <= 200) {
			this.age = age;
		}else {
			throw new RuntimeException("年龄范围不正常");
		}
	}
	@Override
	public String toString() {
		return "[name=" + name + ", gender=" + gender + ", age=" + age + "]";
	}	
}

1.4自定义异常

  • 需继承Exception或Exception的子类,代表特定问题。
  • 异常类型名称望文生义,可在发生特定问题时抛出对应的异常。

常用构造方法:

  • 无参数构造方法。
  • String message参数的构造方法。

(框架中常用自定义异常)

public class BizException extends RuntimeException{
	int code;
	String message;
	public BizException(int code, String message) {
		super();
		this.code = code;
		this.message = message;
	}
	public int getCode() {
		return code;
	}
	public void setCode(int code) {
		this.code = code;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
}

使用

public class TestTh {
	public static void main(String[] args) {
		try {
			Scanner input = new Scanner(System.in);
			System.out.println("请输入一个整数:");
			int num1 = input.nextInt();
			System.out.println("请输入除数");
			int num2 = input.nextInt();
			System.out.println(num1 + "/" + num2 + "=" + num1/num2);
		}catch (InputMismatchException e) {
			throw new BizException(1001,"输入不为整数");
		}catch (ArithmeticException e) {
			throw new BizException(1002,"除数不能为0");
		} catch (Exception e) {
			throw new BizException(1003,"其它异常");
		}
	}
}

1.5异常中方法的覆盖

带有异常声明的方法重写:

  • 方法名、参数列表、返回值类型必须和父类相同。
  • 子类的访问修饰符合父类相同或是比父类更宽。
  • 子类中的方法,不能抛出比父类更多、更宽的检查时异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值