目录
(1)异常类可以分为两种:
????????错误:虚拟机相关问题,导致应用程序中断,程序无法自动恢复或捕获,如系统崩溃、虚拟机错误、动态链接失败。
? ? ? ? 异常:因程序编码错误或外在因素导致的问题,能够被系统捕获并进行处理,不会产生应用程序中断,如除以0,负数开平方根,空指针访问。
(2)Throwable是所有异常类的父类,Error和Exception都继承于此父类,本章对异常的处理一般调用Exception异常类。
(3)Exception异常分为两种类型:
????????非检查型异常:编译器不要求强制处置的异常,一般是因为编码或设计不当产生,异常可以避免。
? ? ? ? 检查型异常:程序运行时因外界因素而导致的异常。
异常分类 | 类名 | 说明 |
非检查型异常 | ArrayIndexOutOfBoundsException | 数组下标越界异常 |
NullPointerException???????? | 空指针访问异常 | |
NumberFormatException | 数字格式化异常 | |
ArithmeticExcetion | 算术异常,如除以0 | |
ClassCastException | 类型转换不匹配异常 | |
SQLException???????? | 数据库访问异常 | |
检查型异常 | IOException | 文件操作异常 |
FileNotFoundException | 文件不存在异常 | |
ClassNotFoundException | 类没找到异常 |
? ? ? ? 当程序执行期间产生异常,会中断正常指令流,所以我们要对异常进行相关处理操作。
? ? ? ? 异常处理机制有两种:
(1)使用try...catch捕获异常,将产生异常的代码放在try之后,如果遇到异常则停止执行try块的代码,跳到catch中进行处理。
(2)使用throws进行抛出异常,若当前方法不知道如何处理发生的异常,则由上一级调用者进行处理,可在上一级定义方法时使用throws声明抛出异常。
? ? ? ? 异常处理机制优点:
(1)异常处理代码和正常的业务代码分离,提高程序的可读性,简化程序结构,保证程序的健壮性。
(2)对不同异常进行分类,保证不同情况下能够对应不同的异常类,充分发挥类的可扩展性和可重用性的优势。
(3)可以对程序产生的异常进行灵活处理,如果有能力处理异常则交给catch捕获并处理,若不然则使用throws声明抛出异常,由上一级调用者处理异常。
? ? ? ? try...catch语句中,catch可以有若干个进行捕获不同类型的异常,catch括号内的类型表示捕获的特定异常类型,而Exception代表捕获任意异常,在Java语言中当遇到一个异常时就会抛出异常并中断程序。
? ? ? ? 如何访问异常信息?
? ? ? ??getMessage():返回该异常的详细描述字符串。
? ? ? ? printStackTrace():将该异常的跟踪栈信息输出到标准错误输出。
? ? ? ? printStackTrace(printStream s):将该异常的跟踪栈信息输出到指定输出流。
? ? ? ? getStackTrace():返回该异常的跟踪栈信息。
? ? ? ? 注意:try和catch语句块用大括号来限制语句。
? ? ? ? 对于下面代码中,try语句中按顺序存在两个异常,算术异常和类型转换异常,当遇到第一个算术异常时抛出异常,并中断程序,所以输出只有算术异常的提醒。
public class test {
public static void main(String args[])
{
try{
int i=10/0;
System.out.println(i);
String s1="apple";
System.out.println(Integer.parseInt(s1));
}
catch(ArithmeticException e) //算术异常
{
e.printStackTrace();
}
catch(NumberFormatException e) //类型转换异常
{
e.printStackTrace();
}
catch(Exception e) //任意异常
{
e.printStackTrace();
}
}
}
输出:?
? ? ? ? / by zero
? ? ? ? Java异常处理机制中,通过finally块,无论try块中代码是否出现异常,也不管catch块是否执行,以及是否在try...catch中存在return语句,都会调用finally语句,一般写的是回收代码,回收物理资源。
? ? ? ? 除非在try...catch中使用sys.exit()强制退出应用程序,否则一定会执行finally代码。
//如上面代码后添加:
finally
{
System.out.println("回收资源");
}
? ? ? ? 在Java7之后增加了这项功能,其实所谓的自动关闭资源就是隐式表达的finally语句,如何隐式表达finally语句呢,就要添加在try后面添加小括号,小括号中一般是初始化一个或多个资源,如打开文件,在try...catch语句结束后,小括号内资源会自动关闭,也就是隐式的执行了一步finally语句,用来回收资源。
? ? ? ? 下面代码由于不存在1.txt文件,所以最后返回找不到指定的文件,fls文件输入流也会被收回。
try(FileInputStream fls=new FileInputStream("1.txt"))
{
System.out.println(fls.read());
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
????????对于try...catch异常语句可以进行嵌套操作,但也会降低程序的可读性。
? ? ? ? 对于多异常捕获问题,可以在catch后面的小括号里添加若干异常类,并用 “ | ” 进行间隔。
try
{
...
}
catch(ArthimeticException | NumberFormatException e)
{
...
}
? ? ? ? throw语句抛出一个异常实例对象,类似于建立一个匿名的异常实例对象,throw语句一般写在try语句的条件语句中,如果发生该条件则调用catch捕获异常,并抛出throw中的语句。
? ? ? ? 下面程序中,如果年龄小于0,则抛出异常,输出请输入一个合法年龄。
public class age {
public static void main(String[] args)
{
while(true)
{
Scanner sc=new Scanner(System.in);
int age=sc.nextInt();
try
{
if(age<0)
{
throw new Exception("请输入一个合法年龄: "); //若年龄小于0抛出异常
}
else
break;
}
catch(Exception e)
{
e.printStackTrace();
}
}
System.out.println("end!");
}
}
? ? ? ? 一般会把可能发生异常的代码写入方法中,在该方法的方法名后面添加throws 异常类。
? ? ? ? 下面代码为第一个实例的改编,仍然输出分母不为0的异常。
public class demo {
public static void main(String[] args)
{
try{
throwsfc(); //调用抛出异常的方法
}
catch(ArithmeticException e)
{
e.printStackTrace();
}
catch(NumberFormatException e)
{
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void throwsfc() throws NumberFormatException,ArithmeticException,Exception
{
int i=10/0;
System.out.println(i);
String s1="apple";
System.out.println(Integer.parseInt(s1));
}
}
? ? ? ? 自定义都继承Exception类或RuntimeException类,抛出异常时候为throw new 自定义异常类()的结构,而不是传统的Exception类。
public class AgeException extends Exception {
public AgeException(String msg)
{
super(msg); //继承父类的构造方法
}
}
? ? ? ? 由于调用父类的构造方法,所以抛出异常输出仍然为“请输入一个合法年龄”?
throw new AgeException("请输入一个合法年龄: "); //抛出异常
参考书籍:《Java 8 基础应用与开发》QST青软实训编