异常
意义:
- 不要指望你的程序永远不会出错,作为程序设计人员,尽可能的将程序设计的健壮,不要等出来了问题再去解决
- Java程序运行过程中所发生的异常事件可以分为两类
- 错误(Error): JVM系统内部错误,资源耗尽等严重情况,对于这类情况,程序基本上是无能为力。
- 异常(Exception): 其他因编程错误或偶然的外在因素导致的一般性问题,对于这种情况,可以用Java提供的Exception机制进行处理,例如
- 对负数开平方根
- 空指针访问
- 试图读取不存在的文件
- 网络连接中断
Error/Exception层次图
Exception的层次关系
- Exception的子类很多,大致可以分为三类,有关IO的IOException,有关运行时异常的RuntimeException,以及其他的异常
- IOException是由于IO系统堵塞等原因引起的异常,包括
- (1) 试图从文件结尾处读取信息
- (2) 试图打开一个不存在或者格式错误的url
- RuntimeException是由于程序编写过程中不周全而引起的,包括:
- (1) 错误的类型转换
- (2) 数组越界访问
- (3) 数字计算错误
- (4) 试图访问一个空对象
- 其他异常
- (1) 用Class.forName()来初始化一个类的时候,字符串参数或对应的类不存在
- (2) 其他
- IOException是由于IO系统堵塞等原因引起的异常,包括
运行时异常/已检查异常
- Java语言规范中将Error的子类和RuntimeException的子类都称为运行时异常,这类异常的特点是:Java编译器不会检查他们(所以也成为未检查异常),编译不会出错,只是在程序运行时才发生异常
- 将除RuntimeException类之外的异常类等成为已检查异常,这类异常的特定是:Java编译器会检查他们,如果在程序中出现这类异常而没有处理的话,Java编译器会编译错误
- 对于RuntimeException,是可以通过编程将这种异常避免,例如:对操作数进行判断,就可以避免出现除0的异常;对数组的长度进行判断,就可以避免数组索引越界的异常
- 对于已检查异常,要在程序中通过
try/catch
进行捕获或通过throws在方法声明的时候将异常抛出
常见未检查异常
ArithmeticException 算术异常
public class TestException {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.println(5/i);
}
}
ArrayIndexOutOfBoundsException数组下标越界异常
public class TestException {
public static void main(String[] args) {
int[] i = new int[3];
System.out.println(i[3]);
}
}
NullPointerException空指针异常
public class TestException {
public static void main(String[] args) {
String name = null;
name.substring(5);
}
}
检查异常
检查异常
public class TestException {
public static void main(String[] args) {
FileInputStream fis = new FileInputStream("D:\\a.txt");
}
}
Java异常处理机制
- Java程序的执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常;
- 当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常
- 如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。
throw关键字
throw 异常对象
public class TestException { public static void main(String[] args) { …. throw new NullPointerException(); … } }
异常的传递
沿方法调用链反向传递
main() m1() m2() throw new NullPointerExcption();
异常处理的第一种方式
throws声明处理异常
//这个时候,如果m2抛出检测异常,会抛向m1 public static void m2() throws FileNotFoundException{ //m2-> 1 throw new FileNotFoundException(); //m2-> 2 }
throws 后面可以声明多个异常
public static void m2() throws FileNotFoundException,EOFException{ //m2-> 1 if(true){ throw new FileNotFoundException(); }else{ throw new EOFException(); } //m2-> 2 }
throws 可以应用父类异常代替子类异常
public static void m2() throws IOFException{ //m2-> 1 if(true){ throw new FileNotFoundException(); }else{ throw new EOFException(); } //m2-> 2 }
异常处理的第二种方式
try....catch
处理异常try{ 代码1; 代码2; }catch(FileNotFoundException e){ //异常处理代码 }
或者
try{ 代码1; throw new FileNotFoundException(); 代码2; }catch(FileNotFoundException e){ //异常处理代码 }
或者
try{ 代码1; if(true) throw new FileNotFoundException(); else throw new EOFException(); 代码2; }catch(FileNotFoundException e){ //异常处理代码 } catch(EOFException e){ //异常处理代码 }
或者
try{
代码1;
if(true) throw new FileNotFoundException();
else throw new EOFException();
代码2;
}catch(IOException e){
//异常处理代码
}
或者
try{
代码1;
if(true) throw new FileNotFoundException();
else throw new EOFException();
代码2;
}catch(FileNotFoundException e){
//异常处理代码
} catch(IOException e){
//异常处理代码
}
try..catch..finally异常处理方式
finally中的内容肯定执行
try{ 代码1; throw new FileNotFoundException(); 代码2; }catch(FileNotFoundException e){ //异常处理代码 }finally{ //肯定执行的内容 }
方法覆盖中的异常
子类的覆盖方法不能比父类的被覆盖方法抛出更多的检测异常
class Super{ public void m1() throws IOException{} } class Sub extends Super{ public void m1() throws IOException{} } -------------------------------------- class Super{ public void m1() throws IOException{} } class Sub extends Super{ public void m1() {} } -------------------------------------- class Super{ public void m1() throws IOException{} } class Sub extends Super{ public void m1() throws FileNotFoundception{} }
message属性与异常追踪与Debug介绍
Exception.printStackTrace()
try{ 代码1; throw new FileNotFoundException(); 代码2; }catch(FileNotFoundException e){ //异常处理代码 e.printStackTrace(); }finally{ //肯定执行的内容 }
Exception类中定义了一个message属性,并提供了一个
getMessage()方法获得message属性的值,同时提供了一个构造方法对其属性赋值Exceptionpublic class TestException{ public static void main(String[] args) { try { throw new NullPointerException("发生空指针异常"); } catch (Exception e) { e.printStackTrace(); //System.out.println(e.getMessage()); } } }
自定义异常
extends Exception 检测异常 当产生时需要异常处理
public class TestException{ public static void main(String [] args) throws MyException { m1(); } public static void m1() throws MyException{ throw new MyException("这是我的异常"); } } class MyException extends Exception{ public MyException(){ } public MyException(String message){ super(message); } }
extends RuntimeException 不需要强制处理
public class TestException{ public static void main(String[] args) { m1(); } public static void m1() throws MyException { throw new MyException("这是我的异常"); } } class MyException extends RuntimeException { public MyException() { } public MyException(String message) { super(message); } }