异常处理、异常处理的总结、抛出异常的新知识点......

一、异常处理:

1、

package com.atguigu.exception;



import java.util.Scanner;



import org.junit.Test;



public class TestException {

   

//  @Test   //直接在@Test上点击导包就可以

//  public void test1() {

//     

//      Scanner s=new Scanner(System.in);

//      int i=s.nextInt();

//      System.out.println(i);

//  }

    //常见的运行时异常

    //1、数组下标越界的异常

    @Test

    public void test2() {

       

    }

}

 

       2、

try{       //try把可能出现异常的代码包起来,方便判断

      //存放可能出现异常的代码

}catch(Exception1 e1){    //如果异常时Exception1类型的,则执行处理方式1

      //处理的方式1

} catch(Exception2 e2){   //如果异常是Exception2类型的,则执行处理方式2

      //处理的方式2

}

…………………….

finally{

      //不管怎样,一定会被执行的代码(不管异常如何,finally方法体中的代码是一定要执行的)

}

 

注:1、try内声明的变量,类似于局部变量,出了try{}语句,就不能被调用

      2、finally是可选的。(类似于switch( ){  }语句内的default语句)。

      3、可以有多个catch语句,try中抛出的异常类对象从上到下去匹配catch中的异常类的类型,一旦满足就执行catch中的代码。执行完,就跳出其后的多条catch语句。

      4、如果异常在catch语句中能够抛出异常,那么try-catch语句外的代码还可以照常执行。因为try-catch异常处理完后,又回归了正常。(如果异常处理了,以后的代码可正常执行)。

      5、若catch中多个异常类型是”并列关系”,孰上孰下都可以

         若catch中多个异常类习惯是”包含”的关系,须将子类放在父类的上面,进行处理。否则报错。

            6、finally中存放的是一定会被执行的代码,不管try中、catch中是否仍有异常未被执行,以及是否有return语句。finally内的语句在try{ }catch(  ){  }...中的return语句前执行。

 

            7、try-catch是可以相互嵌套的。类似if-else……。

      、例如数组下标越界的异常:ArrayIndexOutOfBoundsException(讲解:ArrayIndexOutOfBoundsException的父类异常叫IndexOutOfBoundsException;

IndexOutOfBoundsException的父类异常叫OutOfBoundsException;…最终的祖先是Exception异常,即Exception异常是所有异常的父类。像ArrayIndexOutOfBoundsException等是具体的异常名)。

     

实例解释:

package com.atguigu.exception;



import java.util.InputMismatchException;

import java.util.Scanner;



import org.junit.Test;



public class Example {

    @Test

    public void test1(){

        Scanner s=new Scanner(System.in);

        try {

            int i=s.nextInt();

            System.out.println(i);

        }catch (InputMismatchException e) {

            // TODO: handle exception

                System.out.println("出现类型不匹配的异常!");

        }

    }

}

运行结果:

ewe

出现类型不匹配的异常!

     3

 try{}catch(){}的快捷键:Alt+Shift+Z(可以选中一片,然后右键Surround With来添加try-catch)。

try{ }    catch( ){ }   catch( ){ }类似于if( ){ }   else if( ){ }     else if( ){ }…

try中有错误执行第一个catch,如果第一个catch执行发现了错误,那么第二个catch就不会再执行了。

     4、对于运行时异常来说,可以不显式的进行处理;对于编译异常来说,必须要显式地进行处理。

     5、finally:

package finally00;

public class Testfinally {
    public static void main(String[] args) {
        int i=method();
        System.out.println(i);
    }
    public static int method() {
        /*
         * 正常讲,try中的return会返回并跳出method方法,但是finally内部是一定会执行的,
         * 就会先不返回1;而是执行finally内部的语句,finally内部的语句又会return 2;所以结果。

         *加入try语句中存在异常,就会先执行catch内的语句,然后再执行finally内的语句。
         * */
        try {
            //.........
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("彼此各自安好!");
            return 2;
        }
    }
}

结果:(程序一旦遇到return就会跳出当前的方法,)

彼此各自安好!
2

 

会报错:因为在rty-catch中存在return语句,在try-catch外再写语句也不会执行;写任何语句都没用了。

异常处理方式二:

 

未使用抛出异常的情况;

使用第二种抛出方式:throws ……

Method1( )中出现的异常解决不了抛给method2( );method2( )也解决不了此异常,并抛给了main( )方法;main( )方法也解决不了此异常就抛给了虚拟机。

一个地区(method1( )方法)的案子(异常)办不了,上报给了市里(method2()方法);市里发现这个案子(异常)市里也办不了,交给了省里(main方法),省里发现也办不了就交给了国家部门(虚拟机)。

 

异常处理的方式二:在方法的声明处,显式的抛出该异常对象的类型。

1、格式:如:public static void method1() throws FileNotFoundException,IOException{ }

2、当在此方法内部出现异常的时候,会抛出一个异常类的对象,抛给方法的调用者。

3、 异常的对象可以依次向上抛,直至main中;在向上抛的过程中可以再通过try-catch-finally进行处理。

4、抛出异常的两种方式:try-catch可以看作解决问题的;而throws则是回避问题的方式。

5、代码证明:

package finally00;



import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;



/*

  * 异常处理的方式二:在方法的声明处,显式的抛出该异常对象的类型。

 * 格式:如:public static void method1() throws FileNotFoundException,IOException{ }

 * 当在此方法内部出现异常的时候,会抛出一个异常类的对象,抛给方法的调用者。

 * 异常的对象可以依次向上抛,直至main中;在向上抛的过程中可以再通过try-catch-finally进行处理。

 *抛出异常的两种方式:try-catch可以看作解决问题的;而throws则是回避问题的方式。

 * */

public class TestException {

    public static void main(String[] args) throws FileNotFoundException,IOException{

        try {

            method2();

        } catch (FileNotFoundException e) {

            // TODO: handle exception

            System.out.println(e.getMessage());

        }catch(IOException e) {

            e.printStackTrace();

        }

    }

   

    public static void method2() throws FileNotFoundException,IOException{

        try {

            method1();

        } catch (Exception e) {

            // TODO: handle exception

            e.printStackTrace();

        }

    }

   

    public static void method1() throws FileNotFoundException,IOException{

        FileInputStream fis=new FileInputStream(new File("hello.txt"));

        int b;

        while((b=fis.read())!=-1) {

            System.out.println((char)b);

        }

        fis.close();

    }

}

二、总结:

Java的异常处理:抓抛模型

  1. 抓:异常的处理:有两种方式(①、try-catch-finally;②、throws+异常的类型)
  2. 抛:一旦执行过程中,出现异常,会抛出一个异常类的对象。(自动抛出 vs 手动的抛出(throw + 异常类的对象))。

三、新知识点:

1、手动的抛出异常的例子:(throw new Exception(“传入的类型有误!”);)

 

抛出的异常类既可以是系统自带的异常类,也可以是自己造的异常类。

2自定义异常类:(自定义的异常类用class …,一般自定义的异常类都继承并重写Exception;因为Exception是所有异常类的父类)

①、

package exception;

/*

 *如何定义一个异常类:

 *  1、自定义的异常类继承现有的异常类

 *  2、提供一个序列号,提供几个重载的构造器

 * */

public class MyException extends Exception{  

/*  如果extends的是Exception或IOException则在TestStudent里需要显式的抛出异常(用public void register(int id)throw MyException)*/

    static final long serialVersionUID=-70348975766939L;

   

    public MyException() {

       

    }

    public MyException(String msg) {

        super(msg);

    }

}

②、

package exception;



public class TestStudent {

    public static void main(String[] args) {

        Student s=new Student();

        try {

            s.regist(-12);

            System.out.println(s); //放在此处的,如果有异常的话就不会打印id

        } catch (MyException e) {

            // TODO: handle exception

            System.out.println(e.getMessage());

        }

//      System.out.println(s); //如果是写在这里,不管有没有异常都会打印id

    }

}

class Student{

    int id;

   

    /*  如果extends的是Exception或IOException则在TestStudent里需要显式的抛出异常(用public void register(int id)throw MyException)*/

    public void regist(int id) throws MyException{

        if(id>0) {

            this.id=id;

        }else {

            throw new MyException("传入的学号有误!");

        }

    }



    @Override

    public String toString() {

        return "Student [id=" + id + "]";

    }

   

}
  1. 抛异常的方法的重写原则:

 重写:存在继承的类中;

 子类抛出的异常的类型要小于或等于继承的父类的异常;

 如果大于父类抛出异常的类型是错误的。

代码:

package exception;



import java.io.IOException;

/*

 * 重写:存在继承的类中;

 * 子类抛出的异常的类型要小于或等于继承的父类的异常;

 * 如果大于父类抛出异常的类型是错误的。

 * */

public class TestOverride {

    public static void main(String[] args) {

        A a=new B();   //编译时看左边是A类型

        try {

            a.method1();//因为method1()抛出的类型为IOException类型,所以catch的为IOException

           

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}

class A{

    public void method1() throws IOException{//或者FileNotFoundException等

       

    }

}

class B extends A{

    public void method1() throws IOException{

       

    }

}

四、异常处理的总结:

 

情况一:

package exception;

 

public class ReturnExceptionDemo {

    static void methodA() {

        try {

            System.out.println("进入方法A");

            throw new RuntimeException("制造异常");

        } finally{

            System.out.println("A方法的finally");

            // TODO: handle exception

        }

    }

    static void methodB() {

        try {

            System.out.println("进入方法B");

            return ;

        } finally {

            System.out.println("调用B方法的finally");

            // TODO: handle finally clause

        }

    }

    public static void main(String[] args) {

        try {

            methodA();

        } catch (Exception e) {

            System.out.println(e.getMessage());

            // TODO: handle exception

        }

        methodB();

    }

}

结果:

进入方法A

A方法的finally

制造异常

进入方法B

调用B方法的finally

情况二:

package exception;

 

public class ReturnExceptionDemo {

    static void methodA() {

        try {

            System.out.println("进入方法A");

            throw new RuntimeException("制造异常");

        } finally{

            System.out.println("A方法的finally");

            // TODO: handle exception

        }

    }

    static int methodB() {

        try {

            System.out.println("进入方法B");

            return 1+1;

        } finally {

            System.out.println("调用B方法的finally");

            // TODO: handle finally clause

        }

    }

    public static void main(String[] args) {

        try {

            methodA();

        } catch (Exception e) {

            System.out.println(e.getMessage());

            // TODO: handle exception

        }

        int i=methodB();

        System.out.println(i);

    }

}

结果:

进入方法A

A方法的finally

制造异常

进入方法B

调用B方法的finally

2

情况二:

package exception;

 

public class ReturnExceptionDemo {

    static void methodA() {

        try {

            System.out.println("进入方法A");

            throw new RuntimeException("制造异常");

        } finally{

            System.out.println("A方法的finally");

            // TODO: handle exception

        }

    }

    static int methodB() {

        try {

            System.out.println("进入方法B");

            return 1+1;

        } finally {

            System.out.println("调用B方法的finally");

            return 3;

            // TODO: handle finally clause

        }

    }

    public static void main(String[] args) {

        try {

            methodA();

        } catch (Exception e) {

            System.out.println(e.getMessage());

            // TODO: handle exception

        }

        int i=methodB();

        System.out.println(i);

    }

}

结果:

进入方法A

A方法的finally

制造异常

进入方法B

调用B方法的finally

3

五、异常处理的综合练习:

运行时因为有:int i=Integer.parseInt(args[0]);所以在运行时应该是用:右键--Run As--Run Configurations然后在Arguments栏目中输入两个需要的参数(因为int 了i和j)

package Exception00.exec;



public class EcmDef {

    public static void main(String[] args) {

        try {



        int i=Integer.parseInt(args[0]);//被除数

        int j=Integer.parseInt(args[1]);//除数

        ecm(i,j);

        }catch(NumberFormatException e){

            System.out.println("输入的数据类型不一致");

        }catch(ArrayIndexOutOfBoundsException e) {

            System.out.println("缺少命令行参数");

        }catch(ArithmeticException e){

            System.out.println("分母为0了");

        }catch(EcDef e) {

            System.out.println(e.getMessage());

        }

    }

    public static void ecm(int i,int j) throws EcDef{//利用的是throws来抛出异常,谁调用的cem抛出的异常就传给谁

        if(i<0 || j<0) {

            throw new EcDef("您输入的数值存在负数的错误!");

        }

        else {

            System.out.println(i/j);

        }

    }

}

//自定义异常类

class EcDef extends Exception{

    static final long serialVersionUID=-3387524229948L;

    public EcDef() {

       

    }

    public EcDef(String msg) {

        super(msg);

    }

}

 

运行时因为有:int i=Integer.parseInt(args[0]);所以在运行时应该是用:右键--Run As--Run Configurations然后在Arguments栏目中输入两个需要的参数(因为int 了i和j)

package Exception00.exec;



public class EcmDef {

    public static void main(String[] args) {

        try {



        int i=Integer.parseInt(args[0]);//被除数

        int j=Integer.parseInt(args[1]);//除数

        ecm(i,j);

        }catch(NumberFormatException e){

            System.out.println("输入的数据类型不一致");

        }catch(ArrayIndexOutOfBoundsException e) {

            System.out.println("缺少命令行参数");

        }catch(ArithmeticException e){

            System.out.println("分母为0了");

        }catch(EcDef e) {

            System.out.println(e.getMessage());

        }

    }

    public static void ecm(int i,int j) throws EcDef{//利用的是throws来抛出异常,谁调用的cem抛出的异常就传给谁

        if(i<0 || j<0) {

            throw new EcDef("您输入的数值存在负数的错误!");

        }

        else {

            System.out.println(i/j);

        }

    }

}

//自定义异常类

class EcDef extends Exception{

    static final long serialVersionUID=-3387524229948L;

    public EcDef() {

       

    }

    public EcDef(String msg) {

        super(msg);

    }

}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值