Java异常处理


作者:云都小生


概述



异常即程序在运行过程中,发生了不被期望的事,它阻止了程序的正常运行。而我们在开发过程中,需要做的就是如何去处理这些异常。

我们可以选择抛出这个异常,然后程序终止,也可以选择将错误输出给用户,然后继续运行。

捕捉异常是我们程序员应该做的事,这能让我们的程序变得更加和谐。我们不能碰到异常就随随便便让程序闪退,也不能随随便便把一些乱七八糟用户看不懂的提示信息给到用户。


学习观察异常的提示信息


import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        claculate();
    }

    public static void claculate()
    {
        System.out.println("请输入两个整数:");

        Scanner input = new Scanner(System.in);

        int num1 = input.nextInt();
        int num2 = input.nextInt();

        int result = devide(num1,num2);

        System.out.printf("%s/%s=%s\n",num1,num2,result);
    }

    public static int devide(int num1,int num2)
    {
        return num1/num2;
    }
}

下面是一个简单的异常信息,这个异常是因为,我在一个除法运算的例子中用0做被除数,这会引发异常。

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at ExceptionDemo.Test.devide(Test.java:26)
    at ExceptionDemo.Test.claculate(Test.java:19)
    at ExceptionDemo.Test.main(Test.java:7)

一条一条分析

Exception in thread "main"  //这里指的是异常的线程名
java.lang.ArithmeticException: / by zero    //这里是异常的类型与异常爆发的原因

接下去的那三条,就是异常的栈信息

at ExceptionDemo.Test.devide(Test.java:26)
at ExceptionDemo.Test.claculate(Test.java:19)
at ExceptionDemo.Test.main(Test.java:7)

第一行就是引发程序出现异常的根源,下面的那些,都是一层调用一层的信息。由26引发异常,上一个调用来自19行,19行的上一个调用来自7行。


异常类型



所有的异常都实现了Throwable接口,通常分为Error和Exception。错误是比较严重,一旦程序运行时出现了Error(例如内存不足),程序是一定要被终结的。

下面仅做了解。

异常是可以被处理的,例如IOException(输出输入异常)、RunntimeException(运行时异常)。

RunntimeException包含了ArithmeticException算数异常、NullPointerException空指针异等等。

在编译期间,所有的非RunntimeException都必须处理。


异常处理机制



处理异常的语法是这样的:

try
{
    //可能引发异常的代码 
}
catch(小异常 异常变量名)
{
    //指定类型异常发生时,需要执行的代码
}
catch(Exception ex)
{
    //指定类型异常发生时,需要执行的代码
}
finally
{
    //无论是否发生异常,都一定会执行的代码
}

你可以捕捉多种异常,不过需要满足一个规则——捕捉异常类型的步骤,需要从子类到父类。这件事,儿子能够自己解决,就不需要找到爸爸了。

我们可以在catch里面,提示给用户错误的信息。

catch(Exception ex)
{
    ex.printStackTrace();   //输出完整的异常信息(包含也引发异常的调用栈信息)
}

或者是

catch(Exception ex)
{
    String msg = ex.getMessage();   //得到异常信息
    System.out.println("出现异常,异常信息为" + msg);
}


抛出异常


如果碰到了有些异常,我们处理不了或者是不处理的,我们就需要通过throws语句,通知调用方问题,由调用方自己来处理。

try
{
    //可能引发异常的代码 
}
catch(小异常 异常变量名)
{
    throws; //处理不了,抛给调用方
}
finally
{
    //无论是否发生异常,都一定会执行的代码
}


自定义异常信息



我们可以自己定义异常类

package ExceptionDemo;

public class ExamException extends Exception{

    private static final long serialVersionUID = 1L;    //默认生成的异常序列号

    public ExamException()
    {
        super();    //调用父类的无参构造函数
    }

    public ExamException(String msg)
    {
        super(msg);
    }

    //cause内部的、根源的异常
    public ExamException(String msg,Throwable cause)
    {
        super(msg,cause);
    }

    public ExamException(Throwable cause)
    {
        super(cause);
    }
}

所有自定义的异常类都要继承自Exception类。在这个类中重载了一些方法,一般按照这个类写即可。

public class Student {
    public void kaoShi(int a,int b) throws ExamException
    {
        //当两个操作数超过100时,我们就抛出异常
        if(a >= 100 || b >= 100)
        {
            //创建异常对象
            ExamException ee =  new ExamException("题目太难了,不会做");
            throw ee;
        }
        else
        {
            int sum = a + b;
            System.out.println(sum);
        }
    }
}

这是一个学生类,这个学生类进行考试,一旦考试的题目太难,我们就抛出异常。如果只写throw是不行的,你还需要声明,你这个方法可能会抛出什么异常。

public class Teacher {
    public void schoolTest() throws ExamException
    {
        Student stu = new Student();
        stu.kaoShi(200,1);
    }
}

如果你在这个调用的地方,不想捕捉,就继续在方法参数列表后面,继续抛出这个异常。

public class School {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        System.out.println("举行全校统考");

        try
        {
            teacher.schoolTest();
        }
        catch(ExamException ee)
        {
            System.out.println(ee.getMessage());
        }
        finally
        {
            System.out.println("放学");
        }
    }
}

我们选择在这里捕捉异常,并处理掉。

如果我们想处理,就用try-catch,如果你不处理,就要throws抛出。


面试难点


如果用户在catch块中使用了return语句,同时又在finally编写了代码。若是在try块中发生了异常,finally中的代码会执行吗。

如果catch块中有return,那么finally后面的语句是不会执行的。

如果catch块中有return,那么finally块中的return没有意义。

如果catch块中有return,那么执行顺序如下,先执行完catch块中除return之外的所有代码,然后去执行finally块中的全部代码。最后,再回来执行catch中的return语句。

2018/4/17 15:38:18 @Author:云都小生

阅读更多
版权声明:原创文章,转载注明! https://blog.csdn.net/Cloudkings/article/details/79975795
个人分类: Java SE
相关热词: java异常处理
上一篇Java接口详解
下一篇设计模式——访问者模式
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭