错误与异常
软件系统质量要求
• 软件系统不仅要满足用户的功能需求,还应具有可靠性、稳定性和容错性。
• 在用户操作出现错误时,或遇到不可抗拒的干扰时,软件系统也不能放弃,而必须尽最大努力排除错误继续运行。
错误与异常
• 错误
- 错误(error)是指程序遇到非常严重的不正常状态,不能简单地恢复执行。
- 一般是指在运行时遇到的硬件或操作系统的错误,如内存溢出、操作系统出错、虚拟机出错等。
- 错误对于程序而言是致命性的,错误将导致程序无法运行。
- 错误由程序本身不能处理,只能依靠外界干预,否则会一直处于非正常状态。
• 异常
- 异常(exception)指非致命性错误。
- 一般指在运行程序时硬件和操作系统是正常的,而程序遇到的运行错。如:
整数进行除法运算时除数为0,
操作数超出数据范围,
打开一个文件时发现文件不存在,
网络连接中断等。
- 异常会导致应用程序非正常终止。
• Java语言提供异常处理机制
- 使应用程序自身能够捕获异常,并且能够处理异常。
- 由异常处理部分调整应用程序运行状态,使应用程序仍可继续运行。
错误与异常的分类
• Java类库提供了许多处理错误和异常的类,主要分为两大部分:Error类和Exception类。
- Error类是错误类,由Java虚拟机生成并抛给系统,如内存溢出错误、栈溢出错误、动态链接错误等。例如:
当运行某一个类时,如果没有main()方法,产生错误NoClassDefFoundError。
当使用new分配内存空间时,如果没有可用内存,则产生内存溢出错误:OutOfMemoryError。
- Exception类是异常类,由Java应用程序捕获和处理。
每一种异常对应Exception类的一个子类。
异常对象中包含错误的位置和特征等信息。
Java预定义了多种通用的异常类。
捕获异常并处理
Java异常处理的方式有两种:
• 捕获异常并处理
• 抛出异常
try-catch-finally语句,格式如下:
try
{
…
//可能会产生异常的语句序列
}
catch (ExceptionType1 e1)
{
…
// 异常处理代码,捕获到该类型异常后进行处理
}
catch (ExceptionTypeN eN)
{
…
//异常处理代码,捕获到该类型异常后进行处理
}
finally
{
…
//语句序列,无论是否捕获到异常都必须执行的语句
}
注意:
• 一旦发生异常,将自动匹配catch子句中的异常类型,找到相应的catch子句后,执行该catch语句。
• 如果没有捕获到异常,则所有的catch语句将不执行。
• Finally 语句块总会被执行,无论是否有异常发生,或是否捕获到异常。
• Finally 语句块是可选项。
• Catch 和 finally 可以只有其中一项或两项都有,但必须至少有一项。
例:异常处理程序,使用try-catch-finally语句进行异常处理。
public class TryCatchFinally
{
public static void main (String args[])
{
int i=0;
int a[]={1,2,3,4,5};
for(i=0;i<6;i++)
{
try
{
System.out.print("a["+i+"]/"+i+"="+(a[i]/i));
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.print("捕获到数组下标越界异常!");
}
catch(ArithmeticException e)
{
System.out.print("捕获到算术异常!");
}
catch(Exception e)
{
//输出异常信息
System.out.print("捕获"+e.getMessage()+"异常!");
}
finally
{
System.out.println("i="+i);
}
}
}
}
抛出异常
• 将可能发生的异常转移到上一层调用该成员方法的方法中,就是抛出异常。
• 发生异常的方法不处理该异常,而是由上一层处理。
• 抛出异常有2种子句:
1. throw 异常对象,
2. throws子句。
throw
throw的语法格式如下:throw 异常对象;
其中:
• throw是关键字,用于抛出异常,由try语句捕获并处理。
• 异常对象是程序创建的指定异常类对象。throws
假如一个方法的方法体会产生异常,而该方法体中不想处理或不能处理该异常,则可以在方法声明时,采用throws子句声明该方法,将异常抛出。
throws的语法格式如下:[修饰符] 返回类型 方法名(参数列表) throws 异常类型1, 异常类型2,… { // 方法体 }
public void set(int age) throws Exception
{
if (age>0 && age<150)
this.age = age;
else
throw new Exception("年龄无效"+age);
}
自定义异常类
• 在进行Java应用程序设计时,可以使用类库中已经定义好的异常类。
• 系统预定义的类库有时候不能满足用户需要时,程序员编写应用程序时可以自定义需要的异常类。
• 自定义异常类必须继承已有的异常类,即用户自定义的异常类都必须直接或间接地是Exception类的子类。例题
例:自定义年龄异常类
// AgeException.java / 功能简介:声明自定义异常类。 / public class AgeException extends Exception //无效年龄异常类 { public AgeException(String s){ super(s); //调用父类的构造方法 } public AgeException(){ this(“”); } }
例:自定义异常类的使用// Person1.java /* 自定义异常类的使用。 */
public class Person1
{
private String name; //姓名
private int age; //年龄
public Person1(String name,int age) throws AgeException
{
this.set(name);
this.set(age);
}
public void set(String name)
{
if (name==null || name=="")
this.name = "姓名未知";
else
this.name = name;
}
public void set(int age) throws AgeException
{
if (age>=0 && age<150)
this.age = age;
else
throw new AgeException("无效年龄"+age);
}
public void set(String name, int age) throws AgeException
{
this.set(name);
this.set(age);
}
public String toString()
{
return this.name+","+this.age+"岁";
}
public void print()
{
System.out.println(this.toString());
}
public static void main(String args[])
{
Person1 p1=null;
Person1 p2=null;
try
{
//调用声明抛出异常的方法,必须写在try语句中,否则编译不通过
p1 = new Person1("小李子",36);
p1.set(121);
p2 = new Person1("小王",20);
p2.set(200);
}
catch(AgeException e)
{
//捕获自定义异常类,而非Exception类
e.printStackTrace();//显示异常栈跟踪信息
}
finally
{
p1.print();
p2.print();
}
}
}
总结:
1)自定义类异常类AgeException,
2)发生异常,捕获异常的方法,用了throws子句,抛出异常。
3)抛出的异常由上一级处理。即谁用谁处理。