Java学习笔记: 异常处理

1, 什么是异常, java提供异常机制有什么用?

以下程序执行过程中发生了不正常的情况,而这种不正常的情况叫做 : 异常。

java语言提供了异常处理方式,程序执行过程中出现不正常的情况,java把该异常信息打印到控制台,供程序员参考。程序员看到异常信息之后,可以对程序进行修改,让程序更加健壮。

2, java语言中异常是以什么形式存在的?

1)Java异常在java中以类的形式存在,每一个异常类都可以创建异常对象
2)钱包丢了(异常类):
              2008年,小名的钱包丢了(异常类的对象)
              ....
import java.lang.*;
public class Test04 {
     
    public static void main(String[] args){
     
        int a = 0;
        int b = 1;
        //发生了异常,于是在jvm中new了一个对应异常类的异常对象,然后抛出到控制台.
        int c = b/a;
        //下面证明了异常是一个类
        NumberFormatException nfe = new NumberFormatException("数字格式化异常!");
        System.out.println(nfe);
    }
}

3, java的异常处理机制
异常的继承结构是怎样的?
Java学习笔记: 异常处理_第1张图片
以上还有其他异常未写出,如Excpetion异常类下还有ExcpetionSubClass,RuntimeException…

无论是错误还是异常,都JVM可以抛出。
只要出现错误,程序立刻终止,并抛出异常。
Java学习笔记: 异常处理_第2张图片

  • 所有Exception的直接子类,都叫做编译时异常。编译时异常是在编译阶段发生的吗?不是,编译时异常是表示必须在编写程序的时候预先对这种异常进行处理,如果不处理编译器报错。(提示:ExceptionSubClass就是Exception的直接子类)
  • 所有的RuntimeException及子类都属于运行时异常。运行时异常在编写程序阶段,你可以选择处理,也可以不处理。

4, 所有的异常都是发生在运行阶段,因为发生异常时需要new异常对象

5, 编译时异常发生率较高,运行时异常发生率较低。

6,
受检异常(CheckedException),受控异常叫编译时异常,
未受检异常(UnCheckedException), 非受控异常叫运行时异常。

7,
第一种方式:在方法声明的位置上,使用throws关键字,抛给上一级。
第二种方式:使用try…catch语言进行异常捕捉。
Java中异常发生之后如果一直上抛,然后抛给mian方法,最后抛给JVM
,JVM终止程序

8,

public class Test04 {
     
    public static void main(String[] args){
     
        doSome();
    }
    //表示doSome()方法在执行过程中,可能会出现ClassNotFoundException异常
    public static void doSome() throws ClassNotFoundException  {
     

    }
}

以上程序出错,因为ClassNotFoundException是编译时异常类,因此需要进行处理,反之,改为运行时异常类就不需要处理。

处理方法如下:
第一种方法:直接处理异常

public class Test04 {
     
    public static void main(String[] args){
     
        try{
     
            doSome();
        }catch( ClassNotFoundException e){
     
            e.printStackTrace();
        }

    }
    //表示doSome()方法在执行过程中,可能会出现ClassNotFoundException异常
    public static void doSome() throws ClassNotFoundException  {
     

    }
}

第二种方法:把异常抛给上一级,让上一级去处理异常

public class Test04 {
     
    public static void main(String[] args) throw ClassNotFoundException{
     
               doSome();
    }
    //表示doSome()方法在执行过程中,可能会出现ClassNotFoundException异常
    public static void doSome() throws ClassNotFoundException  {
     

    }
}

9, throws的使用

public class Test04 {
     
    public static void main(String[] args){
     
    //不建议在main方法上使用throws,影响代码的健壮性
    try {
     
        m1();
    }catch(Exception e){
       //这个e保存的是m2中抛出的异常地址
        e.printStackTrace() ;
        System.out.println("异常出现!");
        }
    }
    //可以抛出多个异常,也可以抛出其异常的父类
    private static void m1() throws Exception {
     
        m2();
    }

    private static void m2() throws Exception{
     
        new FileHandler();
    }
}

只要异常没有捕捉,此方法的后续代码不会执行,try…catch…后面代码可以执行。

10, catch后面的小括号中可以写当前异常的父类,catch 可以写多个,同时类型必须从上到下,从小到大。

11, 异常对象有两个非常重要的方法:
获取异常简单的描述信息:

 String msg = exception.getMessage();

打印异常追踪的堆栈信息:

exception.printStackTrace();

一般使用 “打印异常追踪的堆栈信息 ”,因为这样可以追寻到问题根源,方便调整。

public class Test04 {
     
    public static void main(String[] args) {
     

        NullPointerException e = new NullPointerException("空指针异常");
// 获取异常简单的描述信息 
        String msg = e.getMessage();
        System.out.println(msg);
//打印异常追踪的堆栈信息
        e.printStackTrace();
//一般结合try...catch使用
        try{
     
            NullPointerException s = new NullPointerException("空指针异常");
        }Catch(NullPointerException c){
     
                 c.printStackTrace();
        }        
        System.out.println("mian over");
    }
}

12, 关于try…catch中的finally子句

  • 在finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块中的代码出现了异常。
  • finally子句必须和try一起出现,不能单独编写。
  • finally语句通常使用在哪些情况下呢?
    通常在finally语句块中完成资源的释放/关闭。
    因为finally中的代码比较有保障。
    即使try语句块中的代码出现异常,finally中代码也能正常执行。
public class Test04 {
     
    public static void main(String[] args) {
     
      //声明位置放在try外部,这样才能在finally中使用
       FileInputStream fis = null;
       try{
     

       fis = new FileInputStream("D:\\360downloads\\277279.jpg");

       //流使用完需要关闭,因为流会占用资源
       } catch(FileNotFoundException e){
     
           e.printStackTrace() ;
       }catch(IOException f) {
     
           f.printStackTrace() ;
       }catch(NullPointerException f){
     
           f.printStackTrace() ;
       }finally{
     
           //流的关闭放在这里比较保险
           //finally中的代码一定会执行的.
          if(fis != null){
     
               try{
     
                 fis.close() ;
               }catch(IOException e){
     
                   e.printStackTrace() ;
              }
          }
       }
    }
}

就算try中出现return,也会依然执行finally中的代码

public class Test04 {
     
    public static void main(String[] args) {
     
       try{
     
           System.out.println("hello world");//第一执行
           
           return;//第三执行
       }finally{
     
           System.out.println("succeed");//第二执行
       }
    }
}

除非try中出现System.exit(0), 直接退出JVM。

public class Test04 {
     
    public static void main(String[] args) {
     
       try{
     
           System.out.println("hello world");
           
          System.exit(0);//退出JVM
       }finally{
     
           System.out.println("succeed");
       }
    }
}

13,final,finally,finalize有什么区别?(经常出现在笔试题中)

  • final是一个关键字,表示最终的,不变的。
  • finally也是一个关键字,和try联合使用,使用在异常处理机制中,在finally中的代码也最终会执行。
  • finalize()是一个Object类中的一个方法,作为方法名出现, 所以finalize是一个标识符。

14,自定义异常
第一步:编写一个类继承Exception或者RuntimeException。
第二步: 提供两个构造方法,一个是无参数的,一个是带有String参数的。

public class MyException extends Exception{
     
            public MyException(){
     
            }
            public MyException(String S){
     
                 super(S);
            }
}

你可能感兴趣的:(JAVA,java)