Java基础教程【第九章:异常处理】

振华OPPO 发表于 2022/04/22 15:16:09 2022/04/22
【摘要】 @TOC 1. java 异常处理 1.1 什么是异常运行时发生的错误称为异常。处理这些异常就称为异常处理。一旦引发异常,程序将突然中止,且控制将返回操作系统(JVM)。 发生异常后此前分配的所有资源都将保留在相同的状态,这将导致资源漏洞。 1.2 java 的异常处理当一个程序出现错误时,它可能的情况有 3 种:语法错误、运行时错误和逻辑错误。语法错误:是指代码的格式错了,或者某个字母输错...

@TOC

1. java 异常处理

1.1 什么是异常

运行时发生的错误称为异常。处理这些异常就称为异常处理。
一旦引发异常,程序将突然中止,且控制将返回操作系统(JVM)。 发生异常后此前分配的所有资源都将保留在相同的状态,这将导致资源漏洞。

1.2 java 的异常处理

当一个程序出现错误时,它可能的情况有 3 种:语法错误、运行时错误和逻辑错误。

语法错误:是指代码的格式错了,或者某个字母输错了;
运行时错误:是指在程序运行的时候出现的一些没有想到的错误,如:空指针异常,数组越界,除数为零等;
逻辑错误:是指运行结果不预想的结果不一样,这是一种很难调试的错误。

而 java 中的异常处理机制主要是指处理运行时错误,即异常就是运行时错误。

产生异常的原因有 3 种:
1.java 内部发生错误,java 虚拟机产生的异常。
2.编写程序的时候由于错误引起的异常,如:空指针异常,数组越界等。
3.通过 throw 语句生成的异常。这种异常通常称为“检查异常”,用来告知方法的调用着相关信息。

1.3 异常示例

public class Test {
	public void say() {
		System.out.println("Test is say!");
	}
	public static void main(String[] args) {
		Test t = null;
		 t.say();//运行时会发生空指针异常
	}
}

在这里插入图片描述

public class Test {
	public static void main(String[] args) {
		System.out.println(1/0);//会发生除数为0异常
	} 
}

在这里插入图片描述

public class Test {
	public static void main(String[] args) {
		try {
			Class.forName("com.mxp.test.Test");//会发生类加载异常
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
 	}
}

在这里插入图片描述
java 通过面向对象的方法处理异常。在一个方法的运行过程中如果出现了异常,这个方法就会产生代表该异常的一个对象,把它交给运行时系统,运行时系统寻找相应的代码来处理这一异常。其中,生成异常对象,并把它交个运行时系统的过程称为抛出(throw)。运行时系统在方法的调用栈中查找,直到找到能处理该异常的对象的过程称为捕获(catch)。

1.4 异常处理的基础

Java 异常处理机制采用一个统一和相对简单的抛出和处理错误的机制。如果一个方法本身能引发异常,当所调用的方法出现异常时,调用者可以捕获异常使之得到处理;也可以回避异常,这时异常将在调用的堆栈中向下传递,直到被处理。
在这里插入图片描述
Error:用于 Java 运行时系统来显示不运行时系统本身有关的错误 ;
Throwable:所有异常类型都是内置类 Throwable 的子类 ;
Exception:用于用户程序可能捕获的异常,也是用来创建用户异常类型子类的类。

在这里插入图片描述

1.5 异常处理机制

把各种不同类型的异常情况进行分类,用 Java 类来表示异常情况,这种类被称为异常类。把异常情况表示成异常类,可以充分发挥类的可扩展和可重用的优势。

异常流程的代码和正常流程的代码分离,提高了程序的可读性,简化了程序的结构。可以灵活的处理异常,如果当前方法有能力处理异常,就捕获并处理它,否则只需抛出异常,由方法调用者来处理它。

1、 try{} ctach{}语句块处理异常

public class Test {
	public void say(){
		try {//try块包含了可能发生异常的代码
		System.out.println(10/0);
	} catch (ArithmeticException e) {//具体的异常类型或者它的父类,如Exception 
		e.printStackTrace();//输出堆栈的跟踪信息
	}
}
	public static void main(String[] args) {
		new Test().say();
	} 
}

2、 多个 catch 块

public class Test {
	public void say() {
	int[] arr = { 1 };
/*
* 当单独执行下面一条输出语句时,会找到对应的异常类的catch块,并输出异常信息
* 当两条语句一起执行的时候,System.out.println(arr[1])将不会被执行
*/
	try {
		System.out.println(10 / 0);// 会发生除数为0异常
		System.out.println(arr[1]);// 会发生数组越界异常
	} catch (ArithmeticException e) {
		System.out.println("除数为0");
		e.printStackTrace();
	} catch (ArrayIndexOutOfBoundsException e) {
		System.out.println("数组越界");
		e.printStackTrace();
	} 
}
	public static void main(String[] args) {
		new Test().say();
	} 
}

3、finally 块:确保了异常发生时所有的清楚工作都可以得到完成,无论是否出现异常,finally 块中的语句都会被执行。
在这里插入图片描述

public class Test {
	public int say(int i) {
			try {
				System.out.println(10 / i);
		} catch (Exception e) {
			e.printStackTrace();
			return 1;
		} finally { }
		return 2;
	 }
	public static void main(String[] args) {
		System.out.println("say方法:" + new Test().say(1));
	}
 }

1.6 常见异常及用途

在这里插入图片描述

2. throw 语句

异常是通过关键字 throw 抛出,程序可以用 throw 语句引发明确的异常。如:

try { 
	if(flag=null) { 
 		throw new NullPointerException(); 
	} 
} 

throw 语句的操作数一定是 Throwable 类类型或 Throwable 子类类型的一个对象。

3. throws 语句

如果一个方法不想处理异常,可以通过 throws 语句将异常抛向上级调用方法。

public class Test {
//类中ClassNotFoundException异常类型丌处理,而由后来的调用者进行处理,
//可以throws多个异常类型,用逗号隔开
	public void say() throws ClassNotFoundException {
		Class.forName("con.dzh.test.Test");
	}
	public static void main(String[] args) {
		Test t = new Test();
		try {
			t.say();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} 
	}
}

4. 运行时异常

RuntimeException 类及其子类都称为运行时异常,这种异常的特点是 Java 编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用 try-catch 语句捕获它,也没有用 throws 子句声明抛出它,也会编译通过。例如当以下divide()方法的参数 b 为 0,执行“a/b”操作时会出现 ArrithmeticException 异常,它属于运行时异常,Java 编译器不会检查它。

public class Test {
	public void divide(int a, int b) {
		System.out.println(a / b);//当b为0的时候发生异常
 	}
 }

==区分运行时异常和检查异常:==

运行时异常表示无法让程序恢复运行的异常,导致这种异常的原因通常是由于执行了错误操作。一旦出现了错误操作,建议终止程序,因此 Java 编译器不检查这种异常。
检查异常表示程序可以处理的异常,如果抛出异常的方法本身不能处理它,那么方法调用者应该去处理它,从而使程序恢复运行,不至于终止程序。
如果一个方法可能出现检查异常,要么用 try-catch 语句捕获,要么用 throws 子句声明将它抛出,否则会导致编译错误。

运行时异常示例:

public class Test {
	public void say(){
		int[] arr = {1,2,3,4};
		for (int i = 0; i <= arr.length; i++) {
			System.out.println(arr[i]);//会发生异常
		} 
	}
}

需要修改程序代码:

public class Test {
	public void say(){
		int[] arr = {1,2,3,4};
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);//会发生异常
		} 
	} 
}

检查异常:

public class Test {
//该方法可能发生ClassNotFoundException异常
	public void say()throws ClassNotFoundException{
	}
	public void tell(){
		say();//会发生编译错误
	} 
}

修改程序代码:

public class Test {
//该方法可能发生ClassNotFoundException异常
	public void say()throws ClassNotFoundException{
	}
	public void tell(){
		try {
			say();
		} catch (ClassNotFoundException e) {
				e.printStackTrace();
		}
	 } 
 }

==throw 和 throws 的区别:==
1)throw 是语句抛出一个异常;throws 是方法抛出一个异常; throws 可以单独使用,但 throw 不能;
2)throws 出现在方法函数头;而 throw 出现在函数体;
3)throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw 则是抛出了异常,执行 throw 则一定抛出了某种异常;
4)两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

5. 自定义异常

1.内置异常不可能始终足以捕获所有错误,因此需要用户自定义的异常类;
2.用户自定义的异常类应为 Exception 类(或者 Exception 类的子类)的子类;
3.创建的任何用户自定义的异常类都可以获得 Throwable 类定义的方法 ;

public class Test {
	public int[] arr(int size) {
		int[] arr = null;
		if(size<0){
			try {
				throw new ArraySizeException();//发生异常
				} catch (ArraySizeException e) {
					e.printStackTrace();
				} 
		}
		arr=new int[size];
		return arr; 
	}
}

老鲸鱼第4057楼▼
别在该奋斗的时候选择安逸,别在该动脑子的时候动感情 ​​​。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。