1 异常的分类
异常在最大的分类下时Error,和Exception。Error是指那些Java虚拟机无法解决的严重问题;而Exception是因编程错误或偶然外在因素所导致的一般性问题。Error是没办法修正的(至少我目前的水平是这样的),但是Exception是可以的。
Exception又分为两大类,一类是编译时异常(又称checked exception),另一个是运行时异常(unchecked exception)。前者会直接在IDE中进行提示,如果不修正无法运行;后者不会在IDE中提示,只会在运行时报错。因此后者的错误不需要进行考虑。
2 常见的异常
2.1 ArrayIndexOutOfBoundsException
属于运行时错误,不需要异常处理。当越界访问数组时,该异常将出现。
public class ArrayIndex {
public static void main(String[] args) {
int[] arr = new int[5];
System.out.println(arr[7]);
}
}
2.2 NullPointerException
属于运行时错误,不需要异常处理。当访问到空指针对象时,该异常出现。
public class NullPointer {
int data=10;
public static void main(String[] args) {
NullPointer p = new NullPointer();
p = null;
System.out.println(p.data);
}
}
2.3 ArithmeticException
属于运行时错误,不需要异常处理。当进行错误的数学运算时,该异常出现。
public class Arithmetic {
public static void main(String[] args) {
int a = 1;
int b = 0;
System.out.println(a/b);
}
}
2.4 ClassCastException
属于运行时错误,不需要异常处理。当强转类型不相容时,该异常出现。
public class ClassCast{
public static void main(String[] args){
Object obj = new Date();
ClassCast test;
test = (ClassCast)obj;
System.out.println(test);
}
}
3 异常的处理
异常的处理实际上只是要处理编译时异常,让编译能够通过,而对于运行时错误不需要进行异常处理,因为这种错误只有在运行时才会知道,且编译器在会在出现这种异常时停止工作。
异常的处理分为两种机制,一是try-catch-finally,二是throws。前者是就地解决问题,后者是将异常转让其他部分去解决问题。
3.1 try-catch-finally
该结构如下所示
try{
//可能有异常的代码
}catch(/*异常类型1的对象*/){
//处理措施1
}catch(/*异常类型1的对象*/){
//处理措施2
}...[finally{/*一定会执行的代码*/}]
需要提及的有:
- 处理措施里面通常会用到两种方法getMessage()和printStackTrace(),前者是自定义异常时输出内容,后者则是自动输出红字内容。
- finally不是必须的。无论是否有异常要处理还是要return,都将会执行finally里面的代码。
如,我们要处理NumberFormatException。
public class ExceptionHandle {
public static void NumberCast(){
String str = "abc";
try{
int num = Integer.parseInt(str);
}catch(NumberFormatException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
NumberCast();
}
}
3.2 throws
在可能出现异常的方法中不进行直接的处理,并“标记”(throws)好可能出现的异常,谁调用这个方法,谁就要处理这个标记好的异常。仍以处理NumberFormatException为例:
public class ExceptionHandle {
//这是个可能存在异常的方法,throws,抛出这个可能的异常
public static void NumberCast()throws NumberFormatException {
String str = "abc";
int num = Integer.parseInt(str);
}
//main方法调用了这个可能的异常,因此他需要对此进行处理
public static void main(String[] args)
{
try{
NumberCast();
}catch(NumberFormatException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
使用throws需要注意的是,当我们进行可能存在异常方法的重写时,不能抛出比父类方法更大的异常,因为调用这个方法里面标记的异常时按父类异常处理的。
3.3 手动抛出异常
在某些情况下我们可能会需要自己去抛出一些异常去做某些流程控制。他的语法是,先创建一个异常类对象,然后使用关键字throw(注意区分throws)抛出这个对象
public static void main(String[] args) {
NumberFormatException e = new NumberFormatException();
throw e;
}
3.4 自定义异常类
虽然Java已经提供了很多异常类了,但有可能存在一种异常是用户想用的但却不存在,那么这时候需要用自定义异常类。
public class Test {
public static void main(String[] args) throws MyException {
MyException e = new MyException("??",1);
throw e;
}
}
class MyException extends Exception{
static final long serialVersionUID = -3387516993124229948L;
private int idnumber;
public MyException(String message,int id){
super(message);
this.idnumber = id;
}
public int getID(){
return idnumber;
}
}