Java中的异常
Java语言将程序运行过程中所发生的不正常严重错误称为异常,对异常的处理称为异常处理。
它会中断正在运行的程序,正因为如此异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点。
package expection;
public class Test {
public static void main(String[] args) {
System.out.println("111");
System.out.println(1/0);//前提为运行的时候才会发生异常
System.out.println("222");//发生异常之后同级代码将不会运行
}
当程序中发生异常的时候,异常之前的代码将会正常运行,当发现异常后同级代码将不会执行。
异常分类
Throwable中常用方法:
public String getMessage():获取异常信息;
public void printStackTrace():输出异常堆栈中的异常信息下面的类都可以调用
Exception:构造方法:
public Exception():无参构造方法;
public Exception(String message):可以指定详细异常信息的有参构造方法;
Throwable有两个直接子类,Error类和Exception类。
Error : 指合理的应用程序在执行过程中发生的严重问题。当程序发生这种严重错误时,通常的做法是通知用户并中止程序的执行。
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Object> vector = new ArrayList<Object>(10);
for (int i = 1; i < 999999000; i++) {
Object obj = new Object();
vector.add(obj);
}
}
}
Exception:异常可分为运行时异常(RuntimeException)和检查时异常(CheckedException)两种:
1、RuntimeException:运行时异常,即程序运行时抛出的异常。这种异常在写代码时不进行处理,Java源文件也能编译通过。 RuntimeException异常类及其下面的子类均为运行时异常。
public class Test {
public static void main(String[] args) {
String [] array = {"张三","李四","王五"};
loopArray(array, 4);//因为loopArray方法抛出运行时异常,所以调用该方法时即便不对该调用方法的代码进行处 理,java源文件也能通过javac命令将该源文件编译成class文件。
}
public static void loopArray(String [] array, int length){
if(array.length<length){
throw new ArrayIndexOutOfBoundsException();//loopArray方法抛出运行时异常
}
for (int i = 0; i < length; i++) {
System.out.println(array[i]);
}
}
}
2、CheckedException:检查时异常,又称为非运行时异常,这样的异常必须在编程时进行处理,否则就会编译不通过。Exception异常类及其子类(除去RuntimeException异常类及其子类)都是检查时异常。
import java.awt.print.PrinterException;
public class Test {
public static void main(String[] args) {
String [] array = {"张三","李四","王五"};
loopArray(array, 4);
}
public static void loopArray(String [] array, int length) throws PrinterException{
if(array.length<length){
throw new PrinterException("无法遍历该数组:参数length的值超出了数组的长度,遍历失败");
}
for (int i = 0; i < length; i++) {
System.out.println(array[i]);
}
}
}
异常的处理方式
Java中对异常的处理有如下两种方式:
1、通过try、catch和finally关键字捕获异常;
try{
//可能抛出异常的语句块
}catch(SomeException1 e){ // SomeException1特指某些异常
//当捕获到SomeException1类型的异常时执行的语句块
} catch( SomeException2 e){
//当捕获到SomeException2类型的异常时执行的语句块
}finally{
//无论是否发生异常都会执行的代码
}
举例:
public class Test{
public static void main(String[] args) {
try {
String name=null;
System.out.println(name.length());
System.out.println(1/0);
Integer.parseInt("qaq");
} catch (NullPointerException e) {
System.out.println("NULL");
}
catch (ArithmeticException e) {
System.out.println("0");
} catch (Exception e) {//不能放在第一个,类似于else if 范围从小到大
System.out.println("other"+e);
}
一个try可以有多个catch,try不允许单独使用
finally无论try中是否有异常发生,finally中的代码总会执行,一般用于释放资源
public class Test{
public static void main(String[] args) {
try {
Class.forName("");//检查时异常,编译时javac不会通过
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
finally {
System.out.println("无论如何都会执行");
}
}
}
try-catch -finally语法结构:
try…catch…finally异常处理结构中,try语句块是必须的, catch和finally语句块至少出现一个。
注意:如果try语句块包含的是检查时异常,则在没有通过throws抛出该异常类的情况下,try必须和catch一起使用,当该行代码去掉或注销掉时,catch相应的异常语句块必须去掉,如下代码:
public class Test {
public static void main(String[] args){
try {
Class.forName("java.lang.Object");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
多重catch
try语句块中的代码可能会引发多种类型的异常,当引发异常时,会按顺序查看每个 catch 语句,并执行第一个与异常类型匹配的catch语句,其后 catch 语句被忽略。
在捕获异常的时候,应按照“从小到大”的顺序捕获异常,即先子类后父类。
public class TestException {
public static void main(String[] args) {
try {
String[] nameArray = { "小王", "小李", "小高" };
for (int i = 0; i < 4; i++) {
System.out.println(nameArray[i]);
} catch (ArrayIndexOutOfBoundsException e) {// 捕获下标越界异常
System.out.println("发生数组下标越界异常,成功捕获!");
} catch (RuntimeException e) {// 捕获运行时异常
System.out.println("发生运行时异常,成功捕获!");
} catch (Exception e) {// 捕获所有异常
System.out.println("发生异常,成功捕获!");
}
System.out.println("显示完毕!");
}
}
}
finally关键字
Java异常在try/catch块后加入finally块,可以确保无论是否发生异常 finally块中的代码总能被执行。
public class TestException {
public static void main(String[] args) {
try {
String[] nameArray = { "小王", "小李", "小高" };
for (int i = 0; i < 4; i++) {
System.out.println(nameArray[i]);
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数据下标越界,请修改程序!");
System.out.println("调用异常对象的getMessage()方法:");
System.out.println(e.getMessage());
System.out.println("调用异常对象的printStackTrace()方法:");
e.printStackTrace();
return;// finally语句块仍然执行
System.exit(1);//直接退出JVM,finally语句块不再执行
} finally {
System.out.println("显示完毕!");
}
System.out.println("显示完毕!");
}
}