- 异常:
在程序的运行过程当中,可能会出现各种问题,比如:两个数相除,除数为零;数组访问越界;强制类型转换异常等,如果程序不及时处理,程序会自动终止。在程序中出现异常必须要去处理。
- 异常体系结构:
Throwable类继承自Object,Error和Exception类用于处理Java中的异常。Throwable、Error和Exception类的实例和他们的子类的实例都被JVM识别为异常对象。
Error:Error和他的子类被识别为致命的,程序无法修复的错误,这些错误很罕见。在程序中一般不处理Error问题。
Exception类型的异常被认为是课控制的异常,可以在应用程序中捕获并处理,其子类RuntimeException称为运行时异常,该类异常基本上经过程序员努力可以避免,比如:除数为0的情况下,只需要整除前判断一下除数便可以避免,因此这类异常,在程序中可以捕获,也可以不捕获。但是不捕获的时候在程序的运行过程中如果发生错误程序会终止。
另外是非运行时异常,该类异常直接或者间接继承自Exception类,要求程序中必须去捕获并进行处理,程序在编译的时候就会检查程序是否对该类异常进行了处理,如果程序中不捕获为运行时异常,程序将无法通过编译。
- 常见的异常如下:
异常类 | 说明 |
Exception | 异常结构的根类 |
RuntimeException | 运行时异常的根类,他以及其子类不要求程序必须捕获处理。 |
ArithmeticException | 算术运算异常,比如:除数为0,属于运行时异常 |
IllagalArgumentException | 方法接受到非法参数,属于运行时异常 |
ArrayIndexOutOfBoundsException | 数组越界访问异常,属于运行时异常。 |
NullPointerException | 尝试访问null对象的成员时发生的空指针异常,属于运行时异常。 |
IOException | IO异常的根类,属于非运行时异常 |
FileNotFoundException | 文件操作时,找不到文件,属于非运行时异常。 |
在java程序中,异常通过5个关键字进行异常处理,分别是:try,catch,throw,throws和finally。
- try和catch
Java中异常处理的基本结构是:
try{ //可能发生异常的代码 ...... }catch(异常类型 异常对象名){ //异常的处理 ...... } |
说明:java中可已将可能出现异常的代码放在try块中进行监控,程序在运行的过程当中,如果代码出现异常,则终止try块的执行,转到catch块中执行相应的异常处理代码。catch块中的代码有异常的时候才会去执行,没有异常的时候不会进行执行。
例如:
|
注意:
1.try-catch不能单独出现,一个try必须对应至少一个catch。
2.如果出现多个异常可以使用多重catch块,异常声明只能从小到大。
2. finally:
主要使用去写一些在程序发生异常之后还是要执行的代码。
finally中的代码是必定会执行的(在任何情况下都会执行)。
一般在finally中进行一些资源释放的操作。
异常类中的常用的方法:
printStackTrace():(默认调用)主要用来输出异常的信息到控制台,
包括异常发生的原因,发生异常的类以及类中第几行代码,从以上信息就可以确定异常发生的具体位置。
getMessage():返回异常发生的原因。
getStackTrace():获取发生异常的信息,返回一个数组。
public static void main(String[] args) {
int a=3;
int b=0;
try {
//有可能会发生异常的代码
System.out.println(a/b);
int [] arr=null;
System.out.println(arr.length);
}catch(ArithmeticException e) {
//对异常的处理
System.out.println("除数不能为0");
//e.printStackTrace();//用来输出有关异常的信息
//String s=e.getMessage();//获取异常信息
//System.out.println(s);
System.out.println(Arrays.toString(e.getStackTrace()));
}catch (NullPointerException e) {
System.out.println("空指针异常");
}catch (Exception e) {
// TODO: handle exception
}finally {
System.out.println("必须要执行的语句");
}
3. throw:主要是用来引发一个异常
程序在执行的过程当中,如果遇到throw关键字,则停止不会执行后续的代码,
如果他包含在一个try-catch块中则直接跳转到catch进行处理。
语法:throw new 异常类(“异常信息”);
public void test() throws Exception{
Scanner s=new Scanner(System.in);
/*try {*/
System.out.println("请输入长方形的长:");
int chang=s.nextInt();
if(chang<=0) {
throw new MyException("长必须大于0");//自己引发异常
}
System.out.println("请输入长方形的宽:");
/*}catch(Exception e) {
System.out.println("发生了异常:"+e.getMessage());
}*/
}
4. throws:主要作用是抛出一个异常
如果一个方法出现了异常不想去处理则可以将该异常向上抛出,抛给方法的调用者。
异常可以一直向上抛 ,最终抛给JVM,但是不建议抛给JVM,尽量在最后一层进行处理。
语法:修饰符 返回类型 方法名() throws 异常类1,异常类2,....{
}
注意:throws可以一次抛出多个异常。
自定义异常:
1.编写一个java类
2,如果写一个运行时异常继承RuntimeException,如果定义的是非运行时异常则继承Exception.
3.编写一个有一个参数的构造方法,然后去调用父类的一个参数的构造方法。
案例:果园中要卖苹果,如果有三个苹果不合格(重量小于10g)则停止交易。
public class SallApple {
private int count;//记录不合格苹果的数量
//定义存放苹果的容器
private Apple apples[]=new Apple[10];
public SallApple() {
for (int i=0;i<apples.length;i++) {
int w=(int)(Math.random()*30+1);
System.out.println(w);
Apple app=new Apple(w);
apples[i]=app;
}
}
public void sall() throws MyException{
for(int i=0;i<apples.length;i++) {
if(count>3) {
throw new MyException("该箱苹果不合格");
}
if(apples[i].getWight()<10) {
count++;
}
}
System.out.println("交易成功");
}
public static void main(String[] args) {
SallApple s=new SallApple();
try {
s.sall();
} catch (MyException e) {
System.out.println(e.getMessage());
}
}
}