Java如何模拟现实生活的不正常数据(1)——异常

一、异常概述

int a =10;
int b =0;
int c =a/b;
System.out.println(c);

于是控制台出现了

	Exception in thread "main" java.lang.ArithmeticException: / by zero
		at com.javase.excepetion.ExceptionTest01.main(ExceptionTest01.java:7)

这个信息被我们称为异常信息,这个信息是JVM打印的。

(1)什么是异常,有什么用?

一下程序执行过程中发生了不正常的情况,而这种不正常的情况叫做:异常。java语言是很完善的语言,提供了异常的处理方式,以下程序执行过程中出现了不正常情况,java把异常信息打印输出到控制台,供程序员参考,程序员看到异常信息之后,可以对程序,进行修改,让程序更加的健壮。

(2)异常以什么形式存在?

我们现在New一个异常

NumberFormatException n1 = new NumberFormatException("数字转换异常");
System.out.println(n1);

于是控制台便输出了

java.lang.NumberFormatException: 数字转换异常

所以我们发现异常是以类的形式存在的。

(3)异常结构图

(4)编译时异常和运行时异常的区别

)编译时异常发生的概率高,运行时异常发生的概率比较低。

编译时异常举例:

看到外面下雨了,出门的时候已经预料到,如果不打伞,可能会生病。拿一把伞就是对

生病异常发生之前的处理方式,对于一些发生概率较高的异常,需要在运行之前对其进行预处理。

运行时异常举例:

小明走在街上,可能会被轮子砸到。因为这种概率低,所以没必要对它进行预处理。

二、异常的处理方式

(1)在方法声明的位置上,使用throws关键字,抛给上一级

为什么我的doSome()会报错呢?

 因为它继承的父类这个,然而这个父类又继承了编译时的异常。

所以,会报错。

(2)第二种方法:采用try…catch()的方式进行捕捉

一般不建议在main方法上使用throws,因为这个异常如果真正发生了,一定会提供JVM,JVM只有终止。

(3)上报和捕捉的选择

如果系统调用者来处理,则采用上抛。其他情况使用捕捉的方式。

三、异常的两个方法

(1)getMessage()

//获取异常简单描述信息:这个信息实际上就是构造方法上面String参数

(2)printStackTrace();

//打印异常堆栈信息,java后台打印异常堆栈追踪信息的时候,采用了异步线程的方式打印的。

N1.printStackTrace();

就会打印出:

java.lang.NullPointerException: 异常
at com.javase.excepetion.ExceptionTest04.main(ExceptionTest04.java:5)

(3)如何利用异常printStackTrace()方法去调试

如何查看异常追踪信息?如何快速调试程序?

(a)从上往下看

(b)从这里往下看,因为上面是SUN公司写的一定不会有错误的

(c)灰色字体以上都是SUN公司编写的,所以就不用看了。

 (d)看这蓝色字体的第一个,因为后面的蓝色字体全部都是因为第一个导致的。

 四、深入try...catch

(1)代码执行顺序

从上面的例子可以看出,如果try中的f1发生了异常,直接走的是catch里面的方法,接着走try...catch后面的。

 (2)可以多写几个catch

第一个catch是对f1的处理,第二个catch是对f1.read()的处理,但是catch在多写的时候,必须从上到下,遵循从下到大的原则。

(3)catch可以采用“|”的形式

(4)try…catch后面的会执行,不会因为发生了异常,然后就宕机了。

public static void main(String[]args){
    try{
        m1();
        System.out.println("执行成功");
    }catch(FileNotFoundException e){
        e.printStackTrace();
    }
    System.out.println("HelloWorld");
    }

private static void m1() throws FileNotFoundException{
    m2();
   }

private static void m2() throws FileNotFoundException{
    m3();
    }

private static void m3() throws FileNotFoundException{
new FileInputStream("C:\\Users\\赵晓东\\Desktop\\jdkapi1.8_google.CHM");
}
执行成功
HelloWorld

这个说明,我不会因为try...catch的执行,而影响后面。我HelloWorld照样执行。

五、try...catch中可以写finally

(1)关于try...catch中的finally子句:

(a)在finally子句中的代码是最后执行的,并且一定会执行的,即使try语句块中的代码出现了异常。

  (b)finally语句通常使用在哪些情况下?

finally语句块中完成资源的释放/关闭,因为finally中的代码比较有保障,即使try语句块中的代码出现了异常,finally中的代码也会正常执行。

try{
//首先创建一个流对象。
    FileInputStream f1 = new FileInputStream("C:\\Users\\赵晓\\Desktop\\jdkapi1.8_google");
//这时候s会出现空指针异常。
    String s =null;
    System.out.println(s.toString());
    f1.close();
}catch(FileNotFoundException e){
    e.printStackTrace();
}catch(IOException e){
    e.printStackTrace();
}

分析以上程序,f1.close()是在String s=null;之后,如果String s=null;发生了空指针异常之后,fl.close();就不会执行了,这时候流不关闭,会浪费很大的内存。

所以根据以上条件,这时候就要使用finally语句了,也就是不论上面是否执行,我一定会执行我的finally语句。下面语句是我更改之后的。

(2)try和finally,没有catch行吗?

行,但是try不能单独使用。

 

从上面可以看出执行顺序是:先执行try,然后再执行finally,再执行return,所以放在finally语句中的代码一定会执行的。

 但是,退出JVM之后,finally语句中的代码就不执行了。

(3)关于final、finally、finalize的区别

(a)final关键字

final修饰的类是无法继承的,final修饰的方法无法覆盖,final修饰的变量不能重新赋值。

(b)finally关键字

和try一起联合使用

finally语句块中的代码是必须执行的。 

(c)finalize标识符

是一个object类中的方法名,这个方法是由垃圾回收器GC负责调用的。 

(4)finally面试题

以下程序的结果会输出什么?

答案是100,你一定很纠结,那么我们来看一下反编译的代码

public static int m(){
    int i =100;
    int j=i;
    i++;
    return j;
}

 

 总结:以前不知道异常是什么,感觉特别的神奇,现在终于明白了,它就是一个普普通通的类,这个类在不合适逻辑的情况下,会报。我们也可以根据自己的业务写异常,写异常的时候直接继承Exception,然后再写两个构造方法,其中有一个String参数的构造方法,这个构造方法其实是调用了getMessage()方法。还有就是异常的处理两种方式,一种是上抛,一种是采用try...catch的形式进行捕捉,如果你想让调用者处理,你就用第一种t上抛的形式,其余都用try...catch。然后try...catch是能和finally进行试用的,比如我们在最后进行关闭资源的时候,可以把方法写到finally里面。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章