8.1 异常概述
在 Java 语言中,将程序执行中发生的不正常情况称为“ 异常 ”。 (开发过程中的语法错误和逻辑错误不是异常)
package eight1;
public class Baulk {
public static void main(String[] args) {
// TODO Auto-generated method stub
int result = 3 / 0; // 定义int型变量并赋值
System.out.println(result); // 将变量输出
}
}
结果
8.2 异常的分类
1.系统错误——Error
Error 类及其子类通常用来描述 Java 运行系统中的内部错计吴,该类定义了常规环境下不希望由程序捕获的异常,比如OutOfMemoryError、ThreadDeath等,这些错误发生时,Java虚拟机(JVM)一般会选择线程终止。
例如,下面的代码在控制台中输出“梦想照亮现实”这句话活,代码如下:
public static void main(String[] args) {
System.out.println("梦想照亮现实!!!")//此化处缺少必要的分号
}
2.异常——Exception
运行时异常
编译时不会报错,但程序运行起来如果有错误就会报异常。
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
常见的运行时异常:
注:
ConcurrentModificationException 并发修改异常;
NoSuchElementException 找不到元素异常;
UnsupportedOperationException 不支持请求异常;(使用Arrays工具类的asList将数组转成集合增加元素时,会报此异常)
package eight2;
public class Thundering { // 创建类
public static void main(String[] args) { // 主方法
String str = "lili"; // 定义字符串
System.out.println(str + "年龄是:"); // 输出的提示信息
int age = Integer.parseInt("20L"); // 数据类型的转换
System.out.println(age); // 输出信息
}
}
结果
非运行时异常
非运行时异常是RuntimeException类及其子类异常以外的异常,我们必需对出现的这些异常进行处理,否则程序就不能编译通过。如 IOException、SQLException 以及用户自定义的异常等。
注:
反射操作异常:ReflectiveOperationException
方法未找到异常:NoSuchMethodException
字段未找到异常:NoSuchFieldException
非法访问权限异常:IllegalAccessException
实例化异常:InstantiationException
不支持克隆异常:CloneNotSupportedException
被中止异常:InterruptedException
49
package eight3;
public class FootballTeam {
private int playerNum; // 定义“球员数量”
private String teamName; // 定义“球队名称”
public FootballTeam() // 构造方法FootballTeam()
{
// 寻找“教练”类
try {
Class.forName("com.mrsoft.Coach");
} catch (ClassNotFoundException e) { //catch代码块用来获取异常信息
// TODO Auto-generated catch block
e.printStackTrace(); //输出报错信息
}
}
public static void main(String[] args) {
FootballTeam team = new FootballTeam(); // 创建对象team
team.teamName = "com.mrsoft"; // 初始化teamName
team.playerNum = 19; // 初始化playerNum
System.out.println("\n球队名称:" + team.teamName + "\n" + "球员数量:" + team.playerNum + "名");
}
}
结果
8.3 捕捉处理异常
try..catch 代码块主要用来对异常进行捕捉并处理。在实际使用时,该代码块还有一个可选的 finally代码块,其标准语法如下:
try{
//程序代码块
}
catch (Exceptiontype e) {
//对Exceptiontype的处理
}
finally{
//代码块
}
其中,try代码块中是可能发生异常的Java代码; catch 代码块在try代码块之后,用来激发被
捕获的异常;finally代码块是异常处理结构的最后执行行部分,无论程序是否发生异常,finally 代码块中的代码都将执行,因此,在 finally 代码块中通常放置一些释放资源、关闭对象的代码。
1.try...catch 代码块
如果 try 语句块中发生异常,那么一个相应的异常对象就会被拋出,然后 catch 语句就会依据所拋出异常对象的类型进行捕获,并处理。处理之后,程序会跳过 try 语句块中剩余的语句,转到 catch 语句块后面的第一条语句开始执行。
2.finally 代码块
finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
8.4 在方法中抛出异常
1.使用 throws 关键字抛出异常
throws关键字通常被应用在声明方法时,用来指定方法可能抛出的异常,多个异常可使用逗号分隔,使用throws关键字抛出异常的语法格式为:
返回值类型名 方法名(参数表) throws 异常类型名 {
方法体
}
注:使用throws为方法抛出异常时,如果子类继承父类,子类重写方法抛出的异常也要和原父类方法抛出的异常相同或是其异常的子类,除非throws异常时RuntimeException。
package eight6;
public class Shoot { // 创建类
static void pop() throws NegativeArraySizeException {
// 定义方法并抛出NegativeArraySizeException异常
int[] arr = new int[-3]; // 创建数组
}
public static void main(String[] args) { // 主方法
try { // try语句处理异常信息
pop(); // 调用pop()方法
} catch (NegativeArraySizeException e) {
System.out.println("pop()方法抛出的异常"); // 输出异常信息
}
}
}
结果
如果方法抛出了异常,在调用该方法时,必须为捕捉的方法处理异常,当然,如果使用throws关键字将异常抛给上一级后,不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的代码。
2.使用 throw 关键字抛出异常
throw关键字通常用于在方法体中"制造"一个异常,程序在执行到 throw 语句时立即终止,它后面的语句都不执行。使用throw关键字抛出异常的语法格式为:
throw new 异常类型名(异常信息)
throw通常用于在程序中出现某种逻辑错误时,由开发者主动抛出某种特定类型的异常。
例如:
package eight7;
public class ThrowTest {
public static void main(String[] args) { // 主方法
int num1 = 25;
int num2 = 0;
int result;
if (num2 == 0) // 判断num2是否等于0,如果等于0,抛出异常
{
// 抛出ArithmeticException异常
throw new ArithmeticException("这都不会,小学生都知道:除数不能是0!!!");
}
result = num1 / num2; // 计算int1除以int2的值
System.out.println("两个数的商为:" + result);
}
}
结果
注:throw通常用来抛出用户自定义异常,通过throw关键字抛出异常后,如果想在上一级代码中捕获并处理异常,最好在抛出异常的方法声明中使用throws关键字指明要抛出的异常,如果要捕捉throw抛出的异常,则需要使用try…catch代码块。
8.5 自定义异常
自定义异常类的使用步骤如下:
1)自定义异常类继承Exception类;
2)在要抛出异常的函数使用throws关键字;
3)使用 try...catch 代码块捕获并处理异常;
4)再出现异常方法的调用者中捕获并处理异常。
创建自定义异常类,该类继承Exception类:
package eight8;
public class MyException extends Exception { //创建自定义异常,继承Exception类
public MyException(String ErrorMessage) { //构造方法
super(ErrorMessage); //父类构造方法
}
}
创建类Tran,使用throw关键字抛出自定义类异常对象:
package eight8;
public class Tran {
// 定义方法,抛出自定义的异常
static void avg(int age) throws MyException {
if (age < 0) { // 判断方法中参数是否满足指定条件
throw new MyException("年龄不可以使用负数"); // 错误信息
} else {
System.out.println("王师傅今年 " + age + " 岁了!");
}
}
public static void main(String[] args) { // 主方法
try { // try代码块处理可能出现异常的代码
avg(-50);
} catch (MyException e) {
e.printStackTrace();
}
}
}
结果