对java中异常的学习

原创 2015年11月20日 21:19:03

  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 ExceptionRuntime 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语句块的顺序

 

面试常考题型

  try块中的退出语句

  虽然实际开发中不会遇到这样的情况,但是笔试面试时有关异常经常会问到如下情况:

复制代码
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虚拟机,程序会在虚拟机终止前结束执行

版权声明:本文为博主原创文章,未经博主允许不得转载。

JAVA 异常处理的学习

  • 2013年05月06日 15:39
  • 673KB
  • 下载

java异常类的学习(含题目与答案)

  • 2012年03月08日 21:10
  • 149KB
  • 下载

java学习之路 之 异常处理练习题

/** * 异常的分类 : * 1) 按照严重程度 * 1) Error 严重错误 * 2) Exception 普通异常 * 2) 按照处理要求来分 * 1) 受检异常 ...

Java异常学习资料

  • 2010年12月25日 11:49
  • 457KB
  • 下载

JAVA学习代码——异常

1.异常处理:try-catch-final 2.异常链 3.自定义异常 异常处理:try-catch-finalpackage 异常及处理; /**----http://blog.c...

Java基础学习总结(22)——异常处理

一、异常的概念   异常指的是运行期出现的错误,也就是当程序开始执行以后执行期出现的错误。出现错误时观察错误的名字和行号最为重要。    1 package cn.javast...

Effective Java 学习笔记之异常

1) Throwable 所有的异常类的一个共同的祖先2) Error 程序无法处理的错误 表示运行应用程序中比较重要的问题,与代码执行操作无关,表示运行时JVM出现的问题,这些错误表示故障发生于虚拟...

Java IO学习【3】IO中异常的抛出/单个字符读取文件、数组读取字符文件

在前一个IO【2】程序中会发现对文件打开、读取字符数据、关闭文件都需要进行异常的声明,但在【2】中仅仅只是进行了声明,没有办法控制异常抛出时显示的信息,所以在这儿代码里要进行异常的环绕来控制出现异常时...

java学习之异常(二)

异常的类别超类 Throwable:所有异常由 Throwable 类继承而来,它分为 Error类:描述 java 运行时系统的内部错误和资源耗尽错误 Exception类:又分解为 RunTim...

黑马程序员Java学习日记(3)异常,String,多线程

------- android培训、java培训、期待与您交流! ----------      黑马程序员Java学习日记(3)异常,String,多线程 1.异常处理机制: (1)概念:就...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:对java中异常的学习
举报原因:
原因补充:

(最多只允许输入30个字)