java——关于异常处理机制的简单原理和应用2(转)

Java中的异常 Exception

  java.lang.Exception类是Java中所有异常的直接或间接父类。即Exception类是所有异常的根类。

  比如程序:

public class ExceptionTest
{
      public static void main(String[] args)
      {
             int a = 3;
             int b = 0;
             int c = a / b;
             System.out.println(c);
      }
}

 编译通过,执行时结果:

  Exception in thread "main" java.lang.ArithmeticException: / by zero

  at com.learnjava.exception.ExceptionTest.main(ExceptionTest.java:9)

  因为除数为0,所以引发了算数异常。

  比较常见的异常还有这种:空指针异常

  java.lang.NullPointerException是空指针异常,出现该异常的原因在于某个引用为null,但却调用了它的某个方法,这时就会出现该异常。

Java中的异常分为两大类:

  1.Checked Exception(非Runtime Exception

  2.Unchecked ExceptionRuntime Exception

运行时异常

  RuntimeException类是Exception类的子类,它叫做运行时异常,Java中的所有运行时异常都会直接或者间接地继承自RuntimeException类。

  Java中凡是继承自Exception,而不继承自RuntimeException类的异常都是非运行时异常

异常处理的一般结构

 

try
    {
         // 可能发生异常的代码
        // 如果发生了异常,那么异常之后的代码都不会被执行
    }
    catch (Exception e)
    {
        // 异常处理代码
    }
    finally
    {
        // 不管有没有发生异常,finally语句块都会被执行
    }

比如本文最开始的除法运算代码,加入异常处理之后:

public class ExceptionTest
{
    public static void main(String[] args)
    {
        int c = 0;
        try
        {
            int a = 3;
            int b = 0;

            // 这块代码出现了异常
            c = a / b;

            // 那么异常之后的代码都不会被执行
            System.out.println("Hello World");
        }
        catch (ArithmeticException e)
        {
            e.printStackTrace();
        }
        finally
        {
            //不管有没有发生异常,finally语句块都会被执行
            System.out.println("Welcome");
        }

        System.out.println(c);
        // 当b为0时,有异常,输出为c的初始值0
    }
}

输出结果为

多个catch

  一个try后面可以跟多个catch,但不管多少个,最多只会有一个catch块被执行。

异常处理方法

  对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编译。

  处理方式有两种:

  1.使用try..catch..finally进行捕获;

  2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。

  对非运行时异常的处理详见代码例子:

  处理方式1:将异常捕获

将异常捕获

public class ExceptionTest2
{
    public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
    {
        System.out.println("Hello World");

        // 抛出异常
        throw new Exception();
    }

    public static void main(String[] args)
    {
        ExceptionTest2 test = new ExceptionTest2();

        try
        {
            test.method();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            System.out.println("Welcome");
        }

    }

}

处理方式2:将异常继续向外抛出

将异常抛出

public class ExceptionTest2
{
    public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
    {
        System.out.println("Hello World");

        // 抛出异常
        throw new Exception();
    }

    public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
    {
        ExceptionTest2 test = new ExceptionTest2();

        test.method(); // main方法需要对异常进行处理

        // 执行结果:
        // Hello World
        // Exception in thread "main" java.lang.Exception
        // at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)
        // at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
    }

}

对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。

自定义异常

  所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。

  通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。

  自定义异常可以用于处理用户登录错误,用户输入错误提示等。

  自定义异常的例子:

  自定义一个异常类型: 

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

一种处理方式

一种异常处理方式

public class ExceptionTest4
{

    public void method(String str) throws MyException
    {
        if(null == str)
        {
            throw new MyException("传入的字符串参数不能为null!");
        }
        else
        {
            System.out.println(str);
        }
    }

    public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
    {
        ExceptionTest4 test = new ExceptionTest4();
        test.method(null);
    }
}

另一种处理方式

异常处理方式二

public class ExceptionTest4
{

    public void method(String str) throws MyException
    {
        if (null == str)
        {
            throw new MyException("传入的字符串参数不能为null!");
        }
        else
        {
            System.out.println(str);
        }
    }

    public static void main(String[] args)
    {
        //异常处理方式2,采用try...catch语句
        try
        {
            ExceptionTest4 test = new ExceptionTest4();
            test.method(null);

        }
        catch (MyException e)
        {
            e.printStackTrace();
        }
        finally
        {
            System.out.println("程序处理完毕");
        }

    }
}

前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块

  下面这个例子,定义了两种自定义的异常类型:

多种异常 

public class MyException extends Exception
{

    public MyException()
    {
        super();
    }

    public MyException(String message)
    {
        super(message);
    }
}

public class MyException2 extends Exception
{
    public MyException2()
    {
        super();
    }
    public MyException2(String message)
    {
        super(message);
    }

}

public class ExceptionTest4
{

    public void method(String str) throws MyException, MyException2
    {
        if (null == str)
        {
            throw new MyException("传入的字符串参数不能为null!");
        }
        else if ("hello".equals(str))
        {
            throw new MyException2("传入的字符串不能为hello");
        }
        else
        {
            System.out.println(str);
        }
    }

    public static void main(String[] args)
    {
        // 异常处理方式2,采用try...catch语句
        try
        {
            ExceptionTest4 test = new ExceptionTest4();
            test.method(null);

        }
        catch (MyException e)
        {
            System.out.println("进入到MyException catch块");
            e.printStackTrace();
        }
        catch (MyException2 e)
        {
            System.out.println("进入到MyException2 catch块");
            e.printStackTrace();
        }
        finally
        {
            System.out.println("程序处理完毕");
        }

    }
}

我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。

  如果异常类型是独立的,那么它们的前后顺序没有要求。

  如对上面的代码进行改动后,如下列出:

多个catch语句块的顺序

public class ExceptionTest4
{

    public void method(String str) throws Exception // 也可以声明Exception,只要声明的可以涵盖所有抛出的异常即可
    {
        if (null == str)
        {
            throw new MyException("传入的字符串参数不能为null!");
        }
        else if ("hello".equals(str))
        {
            throw new MyException2("传入的字符串不能为hello");
        }
        else
        {
            System.out.println(str);
        }
    }

    public static void main(String[] args)
    {
        // 异常处理方式2,采用try...catch语句
        try
        {
            ExceptionTest4 test = new ExceptionTest4();
            test.method(null);

        }
        catch (MyException e)
        {
            System.out.println("进入到MyException catch块");
            e.printStackTrace();
        }
        catch (MyException2 e)
        {
            System.out.println("进入到MyException2 catch块");
            e.printStackTrace();
        }
        catch (Exception e)
        {
            //虽然需要加上,但是这块代码不会被执行,只是为了编译成功
            System.out.println("进入到MyException catch块");
            e.printStackTrace();
            //如果去掉前面两个catch块或其中之一,则发生该异常时就会进入此catch块
            //catch块的匹配是按照从上到下的顺序,所以这个块如果放在最前面就会捕获所有的异常,后面的块永远不会执行,这时候会提示编译错误
        }
        finally
        {
            System.out.println("程序处理完毕");
        }

    }
}

练习

笔试面试题解析

public class ExceptionTest5
{

    public void method()
    {
        try
        {
            System.out.println("进入到try块");

            //return;
            //会先执行finally块再返回

            //虚拟机退出
            //System.exit(0);
            //不会执行finally块中的语句,直接退出
        }
        catch (Exception e)
        {
            System.out.println("异常发生了!");

        }
        finally
        {
            System.out.println("进入到finally块");

        }

        System.out.println("后续代码");

    }

    public static void main(String[] args)
    {
        ExceptionTest5 test = new ExceptionTest5();
        test.method();
    }
}

在加上return语句前,程序输出:

    进入到try块

    进入到finally块

    后续代码

  如果在try块中加入return语句:

  程序执行输出:

    进入到try块

    进入到finally块

  说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。

  如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。

时间: 2024-10-24 20:50:51

java——关于异常处理机制的简单原理和应用2(转)的相关文章

java——关于异常处理机制的简单原理和应用

异常处理机制的简单原理和应用 一.Execption可以分为java标准定义的异常和程序员自定义异常2种 (1)一种是当程序违反了java语规则的时候,JAVA虚拟机就会将发生的错误表示为一个异常.这里语法规则指的是JAVA类库内置的语义检查. 例如 int i = 2 / 0 或者 String str = null;str.length(); (2)另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常. 例如 Exceptio

Java中的异常处理机制的简单原理和应用。

异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间.地点.人物.情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息. Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Erro

Java中的异常处理机制的简单原理和应用

异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间.地点.人物.情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息. Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Erro

43 java中的异常处理机制的简单原理和应用

异常处理机制的简单原理和应用

java使用面向对象的方式来处理异常,它把程序中发生的每个异常分别封装到一个对象中,该对象包含有异常的信息.所有异常的根类是Throwable, Throwable又派生了两个子类,Error和Exception,Exception包括运行时期异常和编译期异常 运行时期异常的特点: ①方法定义中无需throws声明,调用者也无需try-catch处理此异常. ②运行时期异常一旦发生,需要程序人员修改源代码.(这些异常通常是由于逻辑错误引起的) 一般异常(编译时异常): 必须进行处理的异常,如果不

Java垃圾回收机制的工作原理

Java垃圾回收机制的工作原理 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 一.Java中引入垃圾回收机制的作用 当我们建完类之后,创建对象的同时,进行内存空间的分配,为了防止内存空间爆满,java引入了垃圾回收机制,将不再引用的对象进行回收,释放内存,循环渐进,从而防止内存空间不被爆满. 1.垃圾回收机制的工作原理 创建的对象存储在堆里面,把堆比喻为院子中的土地,把对象比喻为土地的管理者,院子比喻为java虚拟机,当创建一个对象时,java虚拟机将给

Java之异常处理机制

来源:深入理解java异常处理机制 2.Java异常    异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的异常.因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件.当条件生成时,错误将引发异常. Java异常类层次结构图: 图1 Java异常类层次结构图 在 Java 中,所有的异常都有一个共同的祖先 Th

深入理解java的异常处理机制

 JAVA异常的概念    异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的异常.因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件.当条件生成时,错误将引发异常. Java异常类层次结构图: 图1 Java异常类层次结构图 在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出).Thr

java的异常处理机制(try…catch…finally)

1 引子try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的“教训”告诉我,这个东西可不是想象中的那么简单.听话.不信?那你看看下面的代码,“猜猜”它执行后的结果会是什么?不要往后看答案.也不许执行代码看真正答案哦.如果你的答案是正确,那么这篇文章你就不用浪费时间看啦.public class TestException{    public TestException()    {    }    boolean