目录
1、异常
2、异常处理
3、举例
1、异常
(1)概念:异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
(2)异常事件分类:
1)Error:Java 虚拟机无法解决的严重问题。
2)Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。
(3)异常分类:
1)运行时异常:
是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。
(对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对 程序的可读性和运行效率产生影响)
2)编译时异常:
是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求 Java 程序必须捕获或声明所有编译时异常。
(对于这类异常,如果程序不处理,可能会带来意想不到的结果)
(4)常见异常
| 异常类型 | 说明 |
| Exception | 异常层次结构的父类 |
| ArithmeticException | 算术错误情形,如以零作除数 |
| ArrayIndexOutOfBoundsException | 数组下标越界 |
| NullPointerException | 尝试访问 null 对象成员 |
| ClassNotFoundException | 不能加载所需的类 |
| IllegalArgumentException ClassCastException | 方法接收到非法参数 对象强制类型转换出错 |
| NumberFormatException | 数字格式转换异常,如把"abc"转换成数字 |
2、异常处理
方式一:try-catch-finally
方式二:throws + 异常类型
(1)异常处理的方式:try-catch-finally
1)try:
捕获异常的第一步是用 try{…} 语句块选定捕获异常的范围,将可能出现异 常的代码放在 try 语句块中。
2)catch(Exceptiontype e):
在 catch 语句块中是对异常对象进行处理的代码。每个 try 语句块可以伴随一个或多个 catch 语句,用于处理可能产生的不同类型的异常对象。
捕获异常的有关信息:与其它对象一样,可以访问一个异常对象的成员变 量或调用它的方法。
getMessage() 获取异常信息,返回字符串。
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。 返回值 void。
3)finally:
捕获异常的最后一步是通过 finally 语句为异常处理提供一个统一的出 口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。
不论在 try 代码块中是否发生了异常事件,catch 语句是否执行,catch语句是否有异常,catch 语句中是否有 return,finally 块中的语句都会被执行。
finally 语句和 catch 语句是任选的。
4)语法结构
try{
// 可能出现异常的代码
}catch( 异常类型 1 变量名 1){
// 处理异常的方式 1
}catch( 异常类型 2 变量名 2){
// 处理异常的方式 2
}catch( 异常类型 3 变量名 3){
// 处理异常的方式 3
}
...
finally{
// 一定会执行的代码
}
5)说明
a)finally 是可选的。
b)使用 try 将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去 catch 中进行匹配。
c)一旦 try 中的异常对象匹配到某一个 catch 时,就进入 catch 中进行异常的处理。一旦处理完成,就跳出当前的 try-catch 结构(在没有写 finally 的情况)。继续执行其后的代码。
d)catch 中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。 catch 中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错。
e)常用的异常对象处理的方式:
① String getMessage() ② printStackTrace()
f) 在 try 结构中声明的变量,再出了 try 结构以后,就不能再被调用
g)try-catch-finally 结构可以嵌套。
体会 1:使用 try-catch-finally 处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错。相当于我们使用 try-catch-finally 将一个编译时可能出现的异常,延迟到运行时出现。
体会 2:开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写 try-catch-finally 了。 针对于编译时异常,我们说一定要考虑异常的处理。
6)finally 的使用:
A.finally 是可选的。
B.finally 中声明的是一定会被执行的代码。即使 catch 中又出现异常了,try 中有 return 语句,catch 中有 return 语句等情况。
C.像数据库连接、输入输出流、网络编程 Socket 等资源,JVM 是不能自动的回收的,我们需要自己手动的进行资源的释放。此时的资源释放,就需要声明在 finally 中。
(2)异常处理的方式二:throws + 异常类型
1) "throws + 异常类型 " 写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。
一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足 throws 后异常类型时,就会被抛出。异常代码后续的代码,就不再执行!
关于异常对象的产生: ① 系统自动生成的异常对象
② 手动生成一个异常对象,并抛出 (throw)
2) 体会:try-catch-finally:真正的将异常给处理掉了。
throws 的方式只是将异常抛给了方法的调用者。并没有真正将异常处理掉。
(3)手动抛出异常
首先要生成异常类对象,然后通过 throw 语句实现抛出操作 ( 提交给Java 运行环境 )。
可以抛出的异常必须是 Throwable 或其子类的实例。
(4)用户自定义异常类
一般地,用户自定义异常类都是 RuntimeException的子类。
自定义异常类通常需要编写几个重载的构造器。
自定义异常需要提供 serialVersionUID。
自定义的异常通过 throw 抛出。
自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。
如何自定义异常类?
1)继承于现有的异常结构:RuntimeException 、Exception
2)提供全局常量:serialVersionUID
3)提供重载的构造器
3、举例
(1)异常处理
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1 / num2);
System.out.println("感谢使用本程序!");
}
}
import java.util.Scanner;
public class Demo02 {
public static void main(String[] args) {
try {
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1 / num2);
} catch (Exception e) {
e.printStackTrace();
System.out.println("出现了异常");
System.err.print("除数不能为0");
}finally{
System.out.println("感谢使用本程序!");
}
}
}
import java.util.Scanner;
public class Demo03 {
public static void main(String[] args) {
try {
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1 / num2);
// System.exit(1);//结束虚拟机运行
} catch (Exception e) {
e.printStackTrace();
System.out.println("出现了异常");
System.err.print("除数不能为0");
System.exit(1);//结束虚拟机运行
}finally{
System.out.println("感谢使用本程序!");
}
}
}
(2)多重异常处理
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
try {
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1 / num2);
// return;
} catch (Exception e) {
e.printStackTrace();
System.out.println("出现了异常");
System.err.print("除数不能为0");
return;
} finally {
System.out.println("感谢使用本程序!");
}
}
}
import java.util.InputMismatchException;
import java.util.Scanner;
public class Demo02 {
public static void main(String[] args) {
try {
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1 / num2);
} catch (InputMismatchException e) {
System.out.println("要求输入的是整数,不能是其它门类型");
e.printStackTrace();
} catch (ArithmeticException e){
System.out.println("除数不能为0");
e.printStackTrace();
}catch (Exception e){
System.out.println("其它异常处理");
}finally {
System.out.println("感谢使用本程序!");
}
}
}
(3)声明异常
import java.util.InputMismatchException;
import java.util.Scanner;
public class Demo01 {
public static void test() throws InputMismatchException,ArithmeticException{
Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1 + "/" + num2 + "=" + num1 / num2);
}
public static void main(String[] args) throws Exception {
//调用有异常的方法,可以由调用者进行处理
// try {
// test();
// } catch (Exception e) {
// System.out.println("你调用的的方法里有异常");
// }
//调用有异常的方法,可以将异常继续往上声明
test();
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Demo02 {
public static void main(String[] args) {
File file = new File("F:/demo.txt");
try {
FileInputStream fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
(4)手动抛出异常
public class Student {
private String name;
private int age;
private String gender;
public Student() {
super();
}
public Student(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception {
if(age>=1&&age<=100){
this.age = age;
}else{
throw new Exception("年龄应该在1-100之间");
}
}
public String getGender() {
return gender;
}
public void setGender(String gender) throws Exception {
//对性别进行判断
if(gender.equals("男")||gender.equals("女")){
this.gender = gender;
}else{
throw new Exception("性别只能为男或者女,不能是其它数据");
}
}
}
public class StudentTest {
public static void main(String[] args) {
Student stu = new Student();
try {
stu.setGender("东方不败");
} catch (Exception e) {
e.printStackTrace();
}
try {
stu.setAge(120);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(stu.getGender());
System.out.println(stu.getAge());
}
}
(5)自定义异常
public class GenderException extends Exception {
public GenderException(String message){
super(message);
}
}
public class Student {
private String name;
private int age;
private String gender;
public Student() {
super();
}
public Student(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception {
if(age>=1&&age<=100){
this.age = age;
}else{
throw new Exception("年龄应该在1-100之间");
}
}
public String getGender() {
return gender;
}
public void setGender(String gender) throws GenderException {
//对性别进行判断
if(gender.equals("男")||gender.equals("女")){
this.gender = gender;
}else{
throw new GenderException("性别只能为男或者女,不能是其它数据");
}
}
}
public class StudentTest {
public static void main(String[] args) {
Student stu = new Student();
try {
stu.setGender("岳不群");
} catch (GenderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}



