JAVA异常笔记



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


        什么是异常:程序执行过程中的不正常情况。
        异常的作用:增强程序的健壮性。

2、以下程序控制台出现了:
    Exception in thread "main" java.lang.ArithmeticException: / by zero
   at edu.tjdz.javaSE.exception.ExceptionTest01.main(ExceptionTest01.java:25)
这个信息被我们称为:异常信息。这个信息是JVM打印的。
 */

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

        int a =10;
        int b = 0;
        //实际上JVM在执行到此处的时候,会new异常对象:new ArithmeticException(" / by zero");
        //并且JVM将new的异常对象抛出,打印输出信息到控制台。
        int c = a / b;
        System.out.println(a+"/"+b+"="+c);

        //只要是异常发生了,他就会创建该异常对象
        //此处运行也会创建一个:ArithmeticException类型的异常对象
        //System.out.println(10/0);

        //观察到异常之后,对程序进行修改,更加健壮。
        /*
        int a =10;
        int b = 0;
        if(b==0){
            System.out.println("除数不能为0");
            return;
        }
        int c = a / b;
        System.out.println(a+"/"+b+"="+c);
        */

    }
}

**Test02**

package edu.tjdz.javaSE.exception;
/*
java语言当中的异常以什么形式存在的呢?
    1、异常在java中以类的形式存在,每一个异常类都可以创建异常对象。
    2、异常对应的现实生活是怎么样的?
        火灾(异常类):
            2008年8月8日,小明家着火了(异常对象)
            2008年8月9日,小刚家着火了(异常对象)
            2008年9月8日,小红家着火了(异常对象)

        类是:模板
        对象是:实际存在的个体。

        钱包丢了(异常类):
            2008年1月8日,小明钱包丢了(异常对象)
            2008年1月9日,小芳钱包丢了(异常对象)
            ....

 */
public class ExceptionTest02 {

    public static void main(String[] args) {

        //通过“异常类”实例化“异常对象”
        NumberFormatException nfe = new NumberFormatException("数字格式化异常!");

        //java.lang.NumberFormatException: 数字格式化异常!
        System.out.println(nfe);

        //通过“异常类”创建“异常对象”
        NullPointerException npe = new NullPointerException("空指针异常发生了!");

        //java.lang.NullPointerException: 空指针异常发生了!
        System.out.println(npe);

    }
}

**Test03**

package edu.tjdz.javaSE.exception;
/*
1、关于异常在java中以类和对象的形式存在,那么异常的继承结构是怎么样的?
    我们可以使用UML图来描述一下继承的结构。
    画UML图有很多工具,例如:Rational Rose(收费),starUML等...、

   1.1、Object
        Object下有个Throwable(可抛出的)
        Throwable下有两个分支:Error(不可以处理,直接退出JVM)和Exception(可以处理的)
        Exception下有两个分支:
            Exception的直接子类:编译时异常。(要求程序员在编写程序阶段对这些异常进行处理,因此得名编译时异常)
            RuntimeException:运行时异常。(在编写程序阶段程序员可以预先处理,也可以不处理)

    1.2、编译时异常和运行时异常,都是发生在运行阶段。编译阶段异常是不会发生的。编译时异常因此的名。
        因为编译时异常必须在编译(编写)阶段发生的。因为只有在运行阶段才可以new对象。
        因为异常发生就是new异常对象。

    1.3、编译时异常和运行时异常的区别?
        <1>编译时异常一般发生的概率比较高。
            举个例子:
            你看到外面出门之前,倾盆大雨的。
            你出门之前会料到:如果不打伞,可能会生病(生病也是一种异常)。
            而且这个异常发生的概率极高,所以我们出门之前要拿一把伞。
            “拿一把伞”就是对“生病异常”发生之前的一种处理方式。
            对于一些发生较高的异常,要提前进行预处理。

            编译时异常又被称为受检异常,还有叫做受控异常。

        <2>运行时异常一般发生的概率比较低。
            举个例子:
            小明走到大街上,可能会被天上的飞机轮子砸到。
            被飞机轮子砸到也是一种异常。
            但是这种异常发生概率较低。
            在出门之前没必要提前对这种发生概率较低的异常进行预处理。
            如果你处理这种异常,你将会获得很累。

            运行时异常又被称为非受检异常,或非受控异常。

        <3>假设java中没有对异常进行划分,没有分为:编译时异常和运行时异常,
        所有的异常都要在编写程序阶段进行预处理,将是怎么样的效果呢?
            首先,如果这样的话,程序肯定第绝对安全的。
            但是程序员编写程序太累,代码到处都是处理异常的代码。

        1.4、注意:所有运行都是发生在运行阶段的。

        1.5、java语言对异常的处理包括两种方式:
            第一种方式:在方法声明的位置,使用throw关键字、抛给上一级。
                谁调用我,我就抛给谁。抛给上一级。

            第二种方式:使用try...catch语句对异常进行捕捉。
                这个事发生了,谁也不知道,因为我给抓住了。

            举个例子:
                我是某集团的一个销售员,因为我的失误,导致公司损失了1000元,
                “损失1000元”这个可以看做是异常发生了,我有两种处理方式。
                第一种方式:我把这件事告诉我的领导【异常上抛】
                第二种方式:我自己掏腰包把这个钱补上了。【异常的捕捉】

                张三----李四----王五-----CEO

            思考:
                异常发生之后,如果我选择了上抛,抛给调用者,调用者需要对这个异常
                继续处理,那么调用这个异常同样也有两种方式。

          1.6、注意:Java中异常发生之后一直上抛,最终抛给main方法,main方法继续上抛,
                抛给调用者JVM,JVM知道这个异常发生只有一个结果。终止Java程序。

2、什么是UML?有什么用?
    UML是一种统一建模语言。
    一种图标式语言(画图的)
    UML不是只有java中使用。只要是面向对象的编程语言,都有UML。
    一般画UML图的人都是软件架构师或者说是系统分析师。这些级别的人员使用的。
    软件设计人员使用UML。

    在UML图中可以描述类和类之间的关系,程序执行流程,对象的状态等。

    盖大楼和软件开发一样,一个道理。
        盖楼之前,会先由建筑师画图。图纸上一个一个符号都是标准符号。
        这个图纸画完,只要是搞建筑的都能看懂,因为这个图纸上标注这些
        符号都是一种“标准语言”。

    在java软件开发当中,软件分析师/设计师负责设计类,java软件开发人员
    必须要能看懂。
*/
public class ExceptionTest03 {
    public static void main(String[] args) {
        /*
        程序执行到此处发生了ArithmeticException异常,
        底层new了一个ArithmeticException异常对象,
        然后抛出,由于main方法调用了100/0,
        两个异常ArithmeticException抛给了main方法,
        main方法没有处理,将这个异常自动抛给JVM。
        JVM自动终止了程序的执行。
        ArithmeticException继承RuntimeException,属于编译时异常。
        在编译程序阶段不需要对这种异常预先处理。
         */

        System.out.println(100/0);
        System.out.println("Hello Word!");
    }
}

**Test04**

package edu.tjdz.javaSE.exception;
/*
以下代码报错的原因:?
    因为doSome()方法在声明位置上使用了:throws ClassNotFoundException
    而ClassNotFoundException是编译时异常,必须在编写代码时处理,没有处理
    编译器报错。
 */
public class ExceptionTest04 {
    public static void main(String[] args) {
        //main方法中调用doSome方法
        //因为doSome()方法声明的位置上有:throw ClassNotFoundException
        //我们在调用doSome()方法的时候必须对这种异常进行预先的处理。
        //如果不处理,编译器就会报错。
        //doSome();
    }

    /**
     * doSome方法在声明的位置使用了:throws ClassNotFoundException
     * 这个代码表示doSome()方法在执行过程中,有可能会出现ClassNotFoundException异常。
     * 叫做类没有找到。这个异常的父类是:Exception,所以ClassNotFoundException属于编译时异常。
     * @throws ClassNotFoundException
     */
    public static void doSome() throws ClassNotFoundException{
        System.out.println("doSome !!!!");
    }
}

**Test05**

package edu.tjdz.javaSE.exception;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

public class ExceptionTest05 {
    /*
    //第一种处理方式:在方法声明的位置上继续使用:throws,来完成异常的继续上抛。抛给调用者。
    //上抛类似于推卸责任。(继续把异常抛给调用者)
    public static void main(String[] args) throws ClassNotFoundException {
        doSome();
    }
    */

    //第二种处理方式:try...catch进行捕捉。
    //捕捉等于把异常拦下,异常真正解决了。(调用者不知道)
    public static void main(String[] args) {
        try {
            doSome();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void doSome() throws ClassNotFoundException{
        System.out.println("doSome!!!!");
    }
}

**Test06**

package edu.tjdz.javaSE.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.server.ExportException;

/*

处理异常的第一种方式:在方法声明的位置使用throw关键字抛出,谁调用我这个方法,我就抛给谁。抛给调用者来处理。
    //上抛对象必须不能低于当前异常对象
    //抛别的不行,可以抛父类型,或者Exception


处理异常的第二种方式:
    使用try...catch语句对异常进行捕捉。
    这个异常不会上报,自己把这个事情处理了。
    异常抛到此为止,不在上报了。
    //一个方法体当中的代码出现异常之后,如果上报的话,此方法结束。
    所以main方法中出异常,不推荐上报,如果上报,JVM直接停止程序的执行。
    导致异常下面的程序全部输出异常。

注意:
    只要异常没有捕捉,采用上报的方式,此法的后续代码不会执行。
    另外注意,try语句块中任意一行出现异常,该行后面代码不会执行。
    try...catch捕捉之后,后续代码可以执行。

在以后的开发中,出现编译时异常,应该是捕捉还是上抛呢,怎么选?
    如果希望调用者来处理,选择throws
    其他情况使用捕捉的方式。
 */
public class ExceptionTest06 {
    //一般不建议在main方法之后使用throws,因为这个异常如果真正发生了,一定会抛给JVM。JVM只有终止。
    //异常处理机制的作用是增强程序的健壮性。怎么能做到。异常发生不要影响程序的执行。所以
    //一般main方法中异常建议使用try....catch进行捕捉。mian就不要继续上抛了。
    /*public static void main(String[] args) throws Exception {
        System.out.println("main begin!");
        m1();
        System.out.println("main over!");
    }*/

    public static void main(String[] args){
        System.out.println("main begin!");
       try{
            // try尝试
            m1();
            //以上代码出异常,直接进入catch语句块中执行
            System.out.println("hello word!");
        }catch(Exception e){ //catch后面好像一个方法的形参
            //这个分支中可以使用e引用,e引用保存的内存地址是那个new出来异常对象的内存地址。
            //catch是捕捉之后走的路径
            //在catch分支中处理异常
            System.out.println("文件不存在,可能路径错误,也可能该文件已经删除!");
            System.out.println(e);//java.io.FileNotFoundException: E:\-Text document\MYSQL\数据库.txt (系统找不到指定的路径。)
        }

        System.out.println("main over!");
    }

    //throws可以有多个异常,中间用,隔开
    //上抛对象必须不能低于当前异常对象
    //抛别的不行,可以抛父类型,或者Exception
    public static void m1() throws Exception{
        System.out.println("m1 begin!");
        m2();
        System.out.println("m1 over!");
    }

    //抛别的不行,可以抛父类型,或者Exception
    public static void m2() throws IOException {
        System.out.println("m2 begin!");
        //编译器报错方法原因是:m3()方法声明位置上有throw FileNotFoundException
        //这里调用m3()没有对其进行预处理,所以编译报错报错
        //m3();

        m3();
        System.out.println("m2 over!");
    }

    public static void m3() throws FileNotFoundException {
        //调用SUN jdk中的某个类的构造方法
        //这个类还没有接触过,后期IO流就知道了。
        //只是借助这个类学习一下异常异常处理机制。
        //创建一个输入流对象,该留指向一个文件。
        /*
        编译报错原因是什么?
            第一:这里调用了一个构造方法:FileInputStream(String name)
            第二:这个构造方法的声明位置上有:throws FileNotFoundException
            第三:通过类的继承结构看到:FileNotFoundException的父类是IOException,
            IOException的父类是Exception,最终的知,FileNotFoundException是编译时
            异常。

            错误原因?编译时异常要求程序员编写程序阶段必须对它进行处理,不处理编译器就报错。
         */
        //new FileInputStream("E:\\Text document\\MYSQL\\数据库.txt");

        //采用第一种处理方式:在方法声明的位置上使用throws继续上抛。
        new FileInputStream("E:\\Text document\\MYSQL\\数据库.txt");

        System.out.println("如果以上代码出异常,这里会执行????不会");

    }
}

**Test07**

package edu.tjdz.javaSE.exception;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
深入try...catch
    1.catch后面中的小括号中的类型可以使具体的异常类型,也可以是该类异常的父类型。
    2、catch可以写多个。建议catch的时候,精确到一个一个处理。这样有利于程序的调试。
    3、catch写多个的时候,从上到下,必须遵循从小到大。
 */
public class ExceptionTest07 {
    /*
    public static void main(String[] args)  throws Exception,NullPointerException{

    }
    */
    /*
    public static void main(String[] args) throws Exception{

    }
    */

   /* public static void main(String[] args) {
        try {
            new FileInputStream("E:\\Text document-\\MYSQL\\数据库.txt");
            System.out.println("如果以上出现异常,这里就不执行了!!!");
        }catch(FileNotFoundException e){
            System.out.println("文件不存在!!!");
        }

        System.out.println("Hello Word!");
    }
    */
   /*
   public static void main(String[] args) {
       try {
           new FileInputStream("E:\\Text document-\\MYSQL\\数据库.txt");
           System.out.println("如果以上出现异常,这里就不执行了!!!");
       }catch(IOException e){// 多态,IOException e = new FileNotFoundException();
           System.out.println("文件不存在!!!");
       }

       System.out.println("Hello Word!");
   }
   */

    public static void main(String[] args) {
       /* try {
            new FileInputStream("E:\\Text document-\\MYSQL\\数据库.txt");
            System.out.println("如果以上出现异常,这里就不执行了!!!");
        }catch(Exception e){
            System.out.println("文件不存在!!!");
        }*/
        /*
        try {
            //创建输入流
            FileInputStream fis = new FileInputStream("E:\\-Text document\\MYSQL\\数据库.txt");
            //读文件
            fis.read();
            System.out.println("如果以上出现异常,这里就不执行了!!!");
        }catch(FileNotFoundException e){
            System.out.println("文件不存在!!!");
        }catch(IOException e){
            System.out.println("该文件报错了!!");
        }
        */

        /*
        //编译报错

        try {
            //创建输入流
            FileInputStream fis = new FileInputStream("E:\\-Text document\\MYSQL\\数据库.txt");
            //读文件
            fis.read();
            System.out.println("如果以上出现异常,这里就不执行了!!!");
        }catch(IOException e){
            System.out.println("文件不存在!!!");
        }catch(FileNotFoundException e){
            System.out.println("该文件报错了!!");
        }
        */

        try {
            //创建输入流
            FileInputStream fis = new FileInputStream("E:\\Text document\\MYSQL\\数据库.txt");

            //进行数学运算
            System.out.println(100/0);//这个异常是运行时异常,编写程序时可以处理,也可以不处理。

            //JDK8新特性
        }catch(IOException | ArithmeticException  | NullPointerException e)  {
            System.out.println("文件不存在?数字异常?空指针异常?都有可能!");
        }
    }
}

**Test08**

package edu.tjdz.javaSE.exception;

/*
异常对象有两个非常重要的方法:
    获取异常简单的描述信息:
        String msg = exception.getMessage();

    打印异常追踪的堆栈信息:
        exception.printStackTrace();
 */
public class ExceptionTest08 {

    public static void main(String[] args) {
        //这里只是为了测试getMessage()方法,和printStackTrace()方法
        //这里只是new了异常对象,但是没有将异常对象抛出。JVM认为这是一个普通的java对象
        NullPointerException e = new NullPointerException("空指针异常");

        //手动抛异常
        //throws e;

        //获取异常的简单描述信息:这个异常时机上就是构造方法上面String的参数。
        String msg = e.getMessage();
        System.out.println(msg);

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

        for(int i=0;i<=1000;i++){
            System.out.println("i = " +i);
        }

        System.out.println("hello word!");
    }

}

**Test09**

package edu.tjdz.javaSE.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/*
异常对象的两个方法:
    String msg = e.getMessage();
    e.printStackTrace();

以后如何查看异常追踪信息,我们应该怎么看,可以快速调试程序呢?
    异常追踪信息,从上王下一行看。
    但是需要注意的是:SUN写的代码就不用了看了(看包名就知道自己写的还是SUN写的)
    主要问题在自己写的代码上。
 */
public class ExceptionTest09 {
    public static void main(String[] args) {
        try {
            m1();
        }catch(FileNotFoundException e){
            //打印异常堆栈追踪信息!!!
            //在实际开发中,建议使用,养成好习惯。
            //一下这行代码要写上,不然出问题也不知道
            //e.printStackTrace();

            //获取异常的简单信息
            String msg = e.getMessage();
            System.out.println(msg);
        }

        /*
    java.io.FileNotFoundException: E:\Text document-\Java\JAVA++.txt (系统找不到指定的路径。)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at edu.tjdz.javaSE.exception.ExceptionTest09.m3(ExceptionTest09.java:50)
        at edu.tjdz.javaSE.exception.ExceptionTest09.m2(ExceptionTest09.java:46)
        at edu.tjdz.javaSE.exception.ExceptionTest09.m1(ExceptionTest09.java:42)
        at edu.tjdz.javaSE.exception.ExceptionTest09.main(ExceptionTest09.java:19)

            因为50行出问题,导致了46行。
            46行出问题,导致了42行。
            42行出问题,导致了19行。
            应该先查看50行的代码,51行是根源。
         */

        //这里程序不耽误执行,很健壮。(服务器不会因为遇到异常而死机)
        System.out.println("hello word!");
    }

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

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

    private static void m3() throws FileNotFoundException{
        new FileInputStream("E:\\Text document-\\Java\\JAVA++.txt");
    }
}

**Test10**

package edu.tjdz.javaSE.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
关于try...catch中的finally字句:

    1、在finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块出现了异常。
        finally字句必须和try一起出现,不能单独编写。

    2、finally语句通常使用在那些情况?
        通常在在finally语句块中完成资源的关闭/释放。
        因为finally中的代码比较有保障。
        即使tey语句块中的代码出现异常,finally中代码也会正常执行。
 */
public class ExceptionTest10 {
    public static void main(String[] args) {
        FileInputStream fis = null;  //声明位置放在try外面,这样在finally中才能用。
        try{
            fis = new FileInputStream("E:\\Text document\\Java\\JAVA++.txt");
            //开始读文件...

            String s = null;
            //这里一定会出现空指针异常
            System.out.println(s.toString());

            System.out.println("hello word!!");
            //流使用完需要关闭,因为流是占用资源的
            //即使以上程序出现了异常,流也必须关闭!
            //放在这里可能流关闭不了
            //fis.close();
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }catch(NullPointerException e){
            e.printStackTrace();
        }finally {
            System.out.println("hello finally!!!");
            if(fis!=null){
                try {
                    //close方法由异常,采用捕捉的方式
                    fis.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }

        System.out.println("hello !!!");
    }
}

**Test11**

package edu.tjdz.javaSE.exception;

/*
finally语句。
    放在finally语句块中的代码是一定会执行的
 */
public class ExceptionTest11 {
    public static void main(String[] args) {
        /*
        try和finally,没有catch可以吗?可以。
            try不能单独使用。
            try  finally可以联合使用。

        以下代码执行顺序:
            先执行,try...
            在执行,finally...
            最后执行,return(return只要执行这个方法必须结束)
        */
        try{
            System.out.println("try.....");
            return;
        }finally{
            //finally中的语句可以执行到。
            System.out.println("finally.....");
        }

        //这里不能写语句,因为这里的代码是执行不到的。
        //System.out.println("hello word!");

    }
}

**Test12**

package edu.tjdz.javaSE.exception;
/*
fianlly语句
    只有强行退出JVM之后,finally中的语句就不会执行了
*/
public class ExceptionTest12 {
    public static void main(String[] args) {
        try {
            System.out.println("try...");
            //退出JVM
            System.exit(0);//退出JVM之后finally
        } finally {
            System.out.println("finally...");
        }
    }
}

​

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你困了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值