1、异常处理机制:Java中定义了很多异常类,每个异常类都代表一种运行错误,类中包含了该运行错误的信息和处理错误的方法等内容。每当Java程序运行过程中发生一个可识别的运行错误时,即该错误有一个异常类与之对应时,系统都会产生一个相应的该异常的对象,即产生一个异常。一旦异常对象产生,系统就一定有相应的机制来处理它,确保不会产生死机、死循环或其他对OS的损害,从而保证程序运行的安全性。
2、异常的类层次:Throwable类是所有异常和错误类的最上层,此类派生了两个子类:Exception类和Error类。Exception类是所有异常类的父类,Error类是所有错误类的父类,前者供程序使用,后者由系统保留。所有的异常类都分布在:java.lang、java.io、java.util、java.net包中。
3、异常的处理:Java异常处理通过5个关键字控制:try、catch、throw、throws和finally
4、try-catch-finally结构
语法格式:
try{ //try语句块
需要检查的语句;//抛出具体的异常代码
}
cathc(异常类名1 变量名)//catch语句块
{
异常类发生时的处理语句;
……
}
……
catch(异常类名n 变量名)//catch语句块
{
异常类发生时的处理语句;
……
}
finally //finally语句块
{
必须要执行的语句;
}
注:try用来捕获异常,catch用来处理相应异常,finally用以进行异常清理。
5、throw语句——产生异常
实例:
public class Test
{
static void throwDemo()
{
try
{
throw new NullPointerException("demo");
}
catch (NullPointerException e)
{
System.out.println("Caught inside demoproc.");
throw e;//重新抛出异常
}
}
public static void main(String args[])
{
//main方法捕捉并处理throwDemo抛出的异常
try
{
throwDemo();
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
}
6、throws语句:如一个定义的方法中存在异常,可在方法声明的后面加上throws关键字将异常抛出到此方法的调用方法中。
例子:
public class Test
{
static void throwDemo() throws NullPointerException
{
System.out.println("Caught inside demoproc.");
throw new NullPointerException("demo");
}
public static void main(String args[])
{
//main方法捕捉并处理throwDemo抛出的异常
try
{
throwDemo();
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
}
7、自定义异常类:某个应用程序所特有的运行错误,需要开发人员根据实际情况创建自己的异常类。自定义的异常类必须是Throwable类的直接或间接子类,实际应用中,通常以Exception类作为其直接父类。在异常类中定义其属性和方法,或者重载父类的属性和方法。
例子:
public class Test
{
static void student(double score)throws MyException
{
if(score>100)
throw new MyException(score);
System.out.println("此学生的成绩是:"+score);
}
public static void main(String args[])
{
try
{
student(80.5);
student(100.5);
}
catch (MyException e)
{
//System.out.println(e);
//printStackTrace()的输出包含错误信息和轨迹
e.printStackTrace();
}
}
}
class MyException extends Exception
{
//学生成绩>100的异常
private double score;
MyException(double score)
{
this.score=score;
}
public String toString()
{
return "你输入了>100的成绩:"+score;
}
}
8、断言(assertion):
在软件开发中,断言是一种经典的调试和测试方式。Java1.4中新添加了断言的功能,是Java中的一种新的错误检查机制,提供了一种在代码中进行正确检查的机制。在编译或运行Java程序时,可通过相应的参数来打开或关闭断言功能。在实现中,assertion就是在程序中的一条语句,对一个boolean表达式进行检查,程序正确将为ture,否则为false,此时系统将给出警告或退出。
断言包括:assert关键字,assertionerror类,以及在java.lang.classloader中几个新的有关断言的方法。一般来说,assertion用于保证程序最基本、关键的正确性。
断言有两种合法的形式:
§assert expression1;
§assert expression1:expression2;
expression1表示一个布尔表达式,expression2表示一个基本类型或者一个对象,基本类型包括boolan、char、double、float、int和long,由于所有类都是Object的子类,因而可以处理一切对象。运行时,如打开断言功能,expresson1将被计算,若计算的值为flase,此语句将抛出一个AssertionError对象。如果assertion语句包括expression2,程序将计算出expression2的结果,然后将这个结果作为AssertionError的构造函数的参数,来创建AssertionError对象,并抛出此对象。若计算的值为true,expresson2将不被计算。如果在计算表达式时,表达式本身抛出异常,那么assert将停止运行,而抛出这个异常。
断言程序的编译:必须使用JDK1.4及比其更新版本,在使用javac命令时,必须加上-source 1.4,一个简单的例子:javac -source 1.4 Test.java
断言的使用是一个复杂的问题,将涉及程序的风格、断言运用的目标、程序的性质等。通常来说,用来检查一些关键值,这些值对整个程序或者局部功能的完成有很大的影响,这种错误是不容易恢复的。
§检查控制流:在if-then和switch-case语句中,可以在不该被执行的控制流之上,加assert false语句。
例子:程序只能取1、2、3。
switch(x)
{
case 1:。。;
case 2:。。;
case 3:。。;
default:assert false:"x value is invalid:"+x;
}
§在私有函数计算前,检查输入参数是否有效。对一地一些私有函数,要求输入满足一些特定的条件,可在函数开始处使用asser进行参数检查。对于公共函数,通常不用,因为一般来说,公共函数必须对无效的参数进行检查和处理,而私有函数是直接使用的。如某函数要求输入的参数必须不为null,可以在函数开始加上断言:assert parameter1!null:"paramerter is null in test metod";
§在函数计算后,检查函数结果是否有效。对于一些计算函数,运行完成后,某些值需要保证一定的性质,如有一个计算绝对值的函数:assert value>=0:"value should be bigger than 0:"+value;
§检查不变量,有些程序中存在一些不变量,在程序的运行生命周期,这些变量的值都是不变的。这些不变量可能是一简单的表达式,也可能是一个复杂的表达式。对于一些关键的不变量,可以通过assert进行检查。如在一个财会系统中,公司的支出和收入必须保持一定的平衡关系,编写一个表达式检查平衡关系。
private boolean isBalance()
{
............
}
在这个系统中,在一些可能影响这种平衡关系的方法前后,都可以加上断言验证:
assert isBalnace():"balance is destoried";