zoukankan      html  css  js  c++  java
  • Java异常处理机制 try-catch-finally

          Java拥有着强大的异常处理机制,最近初步学习了下,感觉内容还是挺多的,特此来将自己的理解写出来与大家分享。


    一、在Java代码code中,由于使用Myeclipse IDE,可以自动提醒用户哪里有错,并且提供修改方法。很多情况下,当我们调用某个方法时,会提示我们某条语句应该用 try-catch语句来包起来。 但是一直没有去理解这是为什么!!! 举例说明如下:


    ExceptionDemo.java

    package com.package2;
    
    class Demo
    {
    	int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。
    	{
    		return a/b;
    	}
    }
    
    
    public class  ExceptionDemo
    {
    	public static void main(String[] args) 
    	{
    		Demo d = new Demo();
    		try
    		{
    			int x = d.div(4,0);
    			System.out.println("x="+x);
    		}
    		catch (Exception e)//Exception e = new ArithmeticException();
    		{
    			System.out.println("除零啦");
    			System.out.println(e.getMessage());//  / by zero;
    			System.out.println(e.toString());// 异常名称 : 异常信息。
    
    			e.printStackTrace();//异常名称,异常信息,异常出现的位置。
    							//其实jvm默认的异常处理机制,就是在调用printStackTrace方法。
    							//打印异常的堆栈的跟踪信息。
    
    
    		}		
    		
    
    		System.out.println("over");
    
    	}
    }
    为什么会出现提示呢?原因就在于被调用的方法throws了异常,即声明本函数可能会出现异常。

    int div(int a,int b) throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。
        {
            return a/b;
        }

    此处抛出了异常,即任何调用此函数的地方都得准备随时捕获并且处理异常。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          二、异常:就是程序在运行时出现不正常情况。


    异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。
                       其实就是java对不正常情况进行描述后的对象体现。

    对于问题的划分:两种:一种是严重的问题,一种非严重的问题。

    对于严重的,java通过Error类进行描述。
                            对于Error一般不编写针对性的代码对其进行处理。

    对与非严重的,java通过Exception类进行描述。
                               对于Exception可以使用针对性的处理方式进行处理。

    无论Error或者Exception都具有一些共性内容。
    比如:不正常情况的信息,引发原因等。

    Throwable
        |--Error
        |--Exception
               

    任何一个异常或者错误都继承于Throwable类,在Error和Exception下边分别各有N多种子类。


    异常的处理:

    (1)、java 提供了特有的语句进行处理。

    try
    {
        需要被检测的代码;
    }
    catch(异常类 变量)
    {
        处理异常的代码;(处理方式)
    }
    finally
    {
        一定会执行的语句;
    }

    其中,当try中的语句产生异常时,会抛出一个异常对象,并且赋值给语句catch(异常类 变量)中的此变量。


    由于出现异常被捕获之后,程序将不再执行出现异常下边的代码,而直接跳转到try-catch-finally语句块的下边开始执行。所以,在finall{ }语句块中执行的代码一般为释放程序资源,如关闭打开的文件等。


    其中,try-catch-finally块中,finally块在以下几种情况将不会执行。

    (1)finally块中发生了异常。

    (2)程序所在线程死亡。

    (3)在前面的代码中用了System.exit();    (ps这条是经常出现的)

    (4)关闭了CPU



    (2)、其中catch语句用于捕获并且处理异常,常见的处理机制有:getMessage()   toString()  以及printStackTrace()方法

    举例如下:

    上边代码,运行后如下:



    由于进行了异常处理,所以程序执行完毕,“over”被打印出来。如果不加异常处理,JVM会报错,程序会停止执行。由上图可以看出默认的异常处理机制是调用e.printStackTrace()方法,并且终止程序的执行。


    三、对多异常的处理。

    (1)、声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
    (2)、对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
        如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

    举例如下:

    package com.package2;
    
    class Demo
    {
    	int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现问题。
    	{
    
    		int[] arr = new int[a];
    
    		System.out.println(arr[4]);
    
    		return a/b;
    	}
    }
    
    
    class  ExceptionDemo
    {
    	public static void main(String[] args) 
    	{
    		Demo d = new Demo();
    		try
    		{
    			int x = d.div(4,0);
    			System.out.println("x="+x);
    		}		
    		catch (ArithmeticException e)
    		{
    			System.out.println(e.toString());
    			System.out.println("被零除了!!");
    
    		}
    		catch (ArrayIndexOutOfBoundsException e)
    		{
    			System.out.println(e.toString());
    			System.out.println("角标越界啦!!");
    		}
    		catch(Exception e)
    		{
    			System.out.println("hahah:"+e.toString());
    		}
    		
    		
    
    		System.out.println("over");
    
    	}
    }

    当传入a=4,b=1时,运行结果如下所示:


    当传入a=5,b=0时,运行结果如下所示:



    四、自定义异常:


    因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。所以对于这些特有的问题可以按照java的对问题封装的思想。将特有的问题。进行自定义的异常装。

    举例说明如下:
    需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的
    那么就需要对这个问题进行自定义的描述。

    当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。要么在内部try catch处理。要么在函数上声明让调用者处理。

    一般情况在,函数内出现异常,函数上需要声明,此时会发现打印的结果中只有异常的名称,却没有异常的信息。因为自定义的异常并未定义信息。

    如何定义异常信息呢?
    因为父类中已经把异常信息的操作都完成了。所以子类只要在构造时,将异常信息传递给父类通过super语句。那么就可以直接通过getMessage方法获取自定义的异常信息。


    重点!!!自定义异常,必须是自定义类继承Exception。

    继承Exception原因
    :异常体系有一个特点:因为异常类和异常对象都被抛出。他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。

    代码如下:

    package com.package2;
    
    //自定义异常类
    class FuShuException extends Exception //getMessage();
    {
    	private int value;
    
    	//为空的构造方法
    	FuShuException()
    	{
    		super();
    	}
    	//构造方法
    	FuShuException(String msg,int value)
    	{
    		super(msg);
    		this.value = value;
    	}
        
    	//自定义异常类的成员方法,用来定义异常信息。
    	public int getValue()
    	{
    		return value;
    	}
    
    }
    
    class Demo
    {
    	int div(int a,int b)throws FuShuException
    	{
    		//增加判断条件
    		if(b<0)
    			throw new FuShuException("出现了除数是负数的情况------ / by fushu",b);//手动通过throw关键字抛出一个自定义异常对象。
    
    		return a/b;
    	}
    }
    
    
    class  ExceptionDemo
    {
    	public static void main(String[] args) 
    	{
    		Demo d = new Demo();
    		try
    		{
    			int x = d.div(4,-9);
    			System.out.println("x="+x);		
    		}
    		catch (FuShuException e)
    		{
    			System.out.println(e.toString());
    			System.out.println("除数出现负数了");
    			System.out.println("错误的负数是:"+e.getValue());
    		}
    		
    		System.out.println("over");
    
    	}
    }
    
    运行结果如图所示:



    五、throws和throw的区别:
    throws使用在函数上。  throw使用在函数内。
    throws后面跟的异常类,可以跟多个,用逗号隔开。  throw后跟的是异常对象。


    六、运行时异常与编译时异常的区别:

    答:运行时异常:只需要在方法内部抛出异常即可。调用该方法的地方不做任何处理。即程序就是计划让出现运行时异常的程序停止运行

          编译时异常:定义该方法时,需要在方法体上对异常进行抛出。在调用该方法的位置处,必须进行相应的异常处理,即选择捕获或者进行抛出(throws)。即,程序可以继续执行下去。



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • 相关阅读:
    杭电 Problem
    杭电Problem 5053 the sum of cube 【数学公式】
    杭电 Problem 2089 不要62 【打表】
    杭电 Problem 4548 美素数【打表】
    杭电 Problem 2008 分拆素数和 【打表】
    杭电 Problem 1722 Cake 【gcd】
    杭电 Problem 2187 悼念512汶川大地震遇难同胞——老人是真饿了【贪心】
    杭电Problem 1872 稳定排序
    杭电 Problem 1753 大明A+B
    东北林业大 564 汉诺塔
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467333.html
Copyright © 2011-2022 走看看