异常机制的本质是,当程序出现错误时,令程序安全退出的机制。
异常处理,就是指程序在出现问题是依然可以正确执行完毕。
/*
**
*
*/
所有的异常的根类都是java.lang.Throwable。
Throwable下面又有两大子类:Error(错误) 、Exception(例外/异常)
-
Error是程序无法处理的错误,造成这种错误的原因主要是JVM出现了问题,与代码无关。
-
Exception则是程序员编写的代码出现了错误,例如空指针异常(NullPointerException)、数组下标越界异常(ArrayIndexOutOfBoundsException)等。
Exception 是所有异常类的父类,通常下面又分为RuntimeException(运行时异常)和 CheckedException(已检查异常)。
RuntimeException:如ArithmeticException(除以0异常)、NullPointerException(空指针异常)、ClassCastException(类型转换异常)、ArrayIndexOutOfBoundsException(下标越界异常)、NumberFormatException(数字格式异常)等都是派生于RuntimeException类。处理这类异常时,一般不用异常处理机制来解决问题,通常是增加“逻辑处理来避免这些异常”,如果显式地声明或捕捉将会对程序可读性和运行效率影响很大。以下举两个例子说明:
ArithmeticException异常:
public class Test {
public static void main(String[] args) {
int b= 0;
//添加逻辑处理
if(b!=0) {
System.out.println(1/b);
}
}
}
ClassCastException异常:
class Animal {
}
class Dog extends Animal{
}
class Cat extends Animal{
}
public class Test {
public static void main(String[] args) {
Animal a = new Dog();
//添加逻辑处理
if(a instanceof Cat) {
Cat c = (Cat) a;
}
}
}
CheckedException:如IOException、SOLException等,以及用户自定义异常都为CheckedException的派生类。处理此类异常有两种方式解决:
方式一:捕获异常,通过try-catch-finally语句块实现。将要执行的语句放入try语句中,如果某句语句出现异常,则跳出try,即抛出异常,然后由对应类型的异常处理catch(捕捉),最后通过finally语句为异常处理提供一个统一的出口,finally锁指定的代码都要被执行(catch语句可以有多条,finally语句最多只能有一条,根据实际情况设置)。try语句中的一条语句若出现异常,则会跳过该语句后的代码,并且抛出异常。
方式二:声明异常(throws子句)。有些情况下,当前方法不需要处理发生的异常,而是向上传递给调用它的方法来处理,此时就在此方法后声明异常如:
public static void readFile(String fileName) throws FileNotFoundException,IOException{
...........
}
而真正对异常的处理在调用的方法中实现:
public static void main (String [] args) {
try {
readFile("avc.txt");
} catch (FileNotFoundException e){
System.out.println("所需文件不存在");
} catch (IOException e) {
System.out.println("文件读写错误");
}
}
自定义异常
class Person {
private String name;
private int age;
public void setAge (int age) throws IllegalAgeException {
if (age < 0) {
throw new IllegalAgeException ("人的年龄应该大于0");
}
this.age = age;
}
public void setName (String name) throws IllegalNameException {
if (name ==null) {
throw new IllegalNameException("请输入用户姓名!");
}
this.name =name;
}
public String toString() {
return "name is " + name + " and age is " + age;
}
}
class IllegalAgeException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public IllegalAgeException () {
}
public IllegalAgeException(String message) {
super(message);
}
}
class IllegalNameException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public IllegalNameException () {
}
public IllegalNameException(String message) {
super(message);
}
}
public class Test {
public static void main (String[] args) {
Person p = new Person();
try {
p.setAge(-5);
} catch (IllegalAgeException e) {
e.printStackTrace();
}
try {
p.setName(null);
}
catch (IllegalNameException e) {
e.printStackTrace();
System.exit(-1);
}
System.out.println(p);
}
}