二十七.异常捕获及处理

本文详细介绍了Java中的异常处理机制,包括try-catch-finally的使用、异常的捕获与处理、throws和throw关键字的区别,以及如何自定义异常。此外,还探讨了运行时异常的特点和断言的概念,包括断言的开启与关闭,以及其在代码中的应用。通过实例展示了异常处理和断言在实际编程中的重要性。
摘要由CSDN通过智能技术生成

认识异常对程序的影响

异常会造成一个完整的程序在执行过程中中断。
我们来看一下例子:
[完整的程序]

public class Test{
	public static void main(String[] args) {
		
		System.out.println("执行程序");
		System.out.println("执行过程:"+20*3);
		System.out.println("执行完成");
		
	}
}

执行结果:

执行程序
执行过程:60
执行完成

当没有异常的情况程序会从头到尾的执行完毕

[异常的程序]

public class Test{
	public static void main(String[] args) {
		
		System.out.println("执行程序");
		System.out.println("执行过程:"+20/0);
		System.out.println("执行完成");
		
	}
}

执行结果:

执行程序
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at amazon.Test.main(Test.java:7)

当程序中有异常的时候那么不会执行全部,会在异常的地方中断此次执行。

处理异常

一般我们处理异常都是用try…catch…finally来抛出异常

  • try块:放可能会触发异常的代码
  • catch块:当try块触发异常会到catch里面处理
  • finally块:不管有没有异常都会执行里面的代码

搭配,try…catch…finally有三种搭配模式

//第一种
try{
}catch(异常类型  异常对象){
	//异常处理
}finally{
}

//第二种
try{
}finally{
}

//第三种
try{
}catch(异常类型  异常对象){
	//异常处理
}

try块必须要有的

例子:比如我们处理null异常

public class Test{
	public static void main(String[] args) {
		try {
			System.out.println("执行开始");
			Map<String, String> map = null;
			System.out.println(map.get("2121"));
		}catch(NullPointerException e) {	//为null报错
			System.err.println("为null报错");
			e.printStackTrace();
		}finally {
			System.out.println("执行完毕");
		}
	}
}

try块里面触发的异常类型要对应catch(异常类型 e),不然是不会处理异常的

执行结果:

执行开始
为null报错
java.lang.NullPointerException				//e.printStackTrace();
	at amazon.Test.main(Test.java:10)
执行完毕

也就是说,你使用try…catch…finally来处理异常又方便又可以让代码执行到最后。

多个异常处理

同上

多加几个catch块就行了
例子:

public class Test{
	public static void main(String[] args) {
		try {
			System.out.println("执行开始");
			Map<String, String> map = null;
			System.out.println(map.get("2121"));
		}catch(NullPointerException e) {	//为null报错
			System.err.println("为null报错");
			e.printStackTrace();
		}catch(Exception e){
			System.err.println("未知报错");
			e.printStackTrace();
		}finally {
			System.out.println("执行完毕");
		}
	}
}

如果你不知道会报什么异常,就用Excption,这是所有异常的父类,所有异常都可以跑出异常。

throws关键字

throws关键字是用在方法上,用来告诉调用者本方法可能出现的异常,不做异常处理,交给调用方法的上层处理。

语法:修饰符 返回值类型 方法名()throws 异常类型,异常类型{ }

例子:

public class Test{
	public static void main(String[] args) {
		try {
			System.out.println(show(19));
		}catch(Exception e){
			System.err.println("未知报错");
			e.printStackTrace();
		}
	}
	
	public static int show(int x)throws Exception{
		
		return x/0;
	}
}

输出结果:

未知报错
java.lang.ArithmeticException: / by zero
	at amazon.Test.show(Test.java:16)
	at amazon.Test.main(Test.java:7)

throws关键字是不做异常处理,只把异常抛出给上一层,上层怎么处理这个异常都和throw是没关系了。

throw关键字

throw关键字是写在方法块里面的,由人为自定义抛出异常,。
例子:

public class Test{
	public static void main(String[] args) {
		try {
			throw new Exception("未知错误");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
}

输出结果:

java.lang.Exception: 未知错误
	at amazon.Test.main(Test.java:7)

异常处理模型

上面已经把异常处理的的方式都说明了,throw、throws、try…catch…finally。
接下来我们结合一起使用

当使用throws关键字处理异常的时候,方法里面不用写catch块因为throws是往上抛出异常的

public class Test{
	public static void main(String[] args) {
		try {
			show();
		} catch (Exception e) {
			// TODO: handle exception
			System.err.println("报错");
			e.printStackTrace();
		}
	}
	
	public static void show() throws Exception{
		try {
			
			System.out.println("执行开始");
			System.out.println( 10/0);
		}finally{
			System.out.println("执行结束");
		}
	}
}

执行结果

执行开始
执行结束
报错
java.lang.ArithmeticException: / by zero
	at amazon.Test.show(Test.java:19)
	at amazon.Test.main(Test.java:7)

使用throw关键字在同方法内,要使用用try…catch块,因为throw是手动抛出异常在说明位置都由自己控制

public class Test{
	public static void main(String[] args) {
		try {
			throw new Exception("报错");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
}

执行结果

java.lang.Exception: 报错
	at amazon.Test.main(Test.java:7)

RuntimeException

RuntimeException(运行时异常),是不受检查的,就是你在编译的时候是不会给你提示某个地方会报错,只有在运行的时候出现。运行时异常不需要try…catch…或throws 机制去处理的异常,如果发生了该异常一定是程序员的问题。

比如经典的1/0,空指针等这些都会在程序运行的时候报错。

自定义异常类

继承Exception或RuntimeException就可以自定义异常类了

//测试类
public class Test{
	public static void main(String[] args) {
		try{
			throw new MyExcetion("10不能处于0");
		}catch(MyExcetion e){
			e.printStackTrace();
		}
	}
}

//自定义异常类  也可以继承RunTimeException
class MyExcetion extends Exception{
	
	//创建无参构造
	public MyExcetion(){}
	//创建有参构造
	public MyExcetion(String message){
		super(message);	// 把参数传递给Throwable的带String参数的构造方法 
	}
}

Assert断言

简介

断言相当于是一个if判断条件,为true的时候正常运行,为false的时候中断运行然后抛出报错。
断言可以随时开启和关闭
断言不具备继承性,也就是说父类禁止断言子类也可以开启断言。

判断

//测试类
public class Test{
	public static void main(String[] args) {
		
		boolean bool = false;		
		
		assert bool = true;		
		
		System.out.println(bool);	//如果打开了断言则会为true
		
	}
}

开打关闭断言

  • 选择菜单:run --> run Configurations
  • 打开断言:-ea
  • 关闭断言:-da,或者删除-ea

在这里插入图片描述

使用方法

例子1:

public class CeShiText {

	public static void main(String[] args) {
			
			assert(1>2);		
			
			System.out.println("执行完成");				
	}
}

和抛出异常差不多,断言为false就会抛出报错AssertionError

执行结果

Exception in thread "main" java.lang.AssertionError
	at amazon.CeShiText.main(CeShiText.java:7)

例子2:

public class CeShiText {

	public static void main(String[] args) {
		boolean boo = false;
		
		try {
			assert boo :"执行错误";
		
			System.out.println("执行成功");
		} catch (AssertionError  e) {
			System.out.println(e.getMessage());
		}
	}
}

执行结果

执行错误

这种方式是如果为true则忽略冒号后面的直接往下执行,如果为false则抛出AssertError异常,而内容则是冒号后面的。

设置断言的使用范围

-ea java -ea 打开所有用户类的assertion
-da java -da 关闭所有用户类的assertion
-ea: java -ea:MyClass1 打开MyClass1的assertion
-da: java -da: MyClass1 关闭MyClass1的assertion
-ea: java -ea:pkg1 打开pkg1包的assertion
-da: java -da:pkg1 关闭pkg1包的assertion
-ea:… java -ea:… 打开缺省包(无名包)的assertion
-da:… java -da:… 关闭缺省包(无名包)的assertion
-ea:… java -ea:pkg1… 打开pkg1包和其子包的assertion
-da:… java -da:pkg1… 关闭pkg1包和其子包的assertion
-esa java -esa 打开系统类的assertion
-dsa java -dsa 关闭系统类的assertion

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值