A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孙汇川 黑马帝   /  2012-2-10 17:12  /  3127 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

大家帮看下这个程序为什么编译的时候就出现两个异常呢?

class Demo
{
        int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException
        {

                int[] arr = new int[a];

                System.out.println(arr[4]);

                return a/b;
        }
}


class  ExceptionDemo2
{
        public static void main(String[] args) //throws Exception
        {
                Demo d = new Demo();
                try
                {
                        int x = d.div(5,0);
                        System.out.println("x="+x);
                }
               
                catch(Exception e)
                {
                        System.out.println("hahah:"+e.toString());
                }
                catch (ArithmeticException e)
                {
                        System.out.println(e.toString());
                }
                catch (ArrayIndexOutOfBoundsException e)
                {
                        System.out.println(e.toString());
                }
               
                               

                System.out.println("over");

        }
}

评分

参与人数 1技术分 +1 收起 理由
admin + 1 弄懂了?

查看全部评分

11 个回复

正序浏览
maochong 黑马帝 2012-2-13 18:28:56
12#
捕捉所有异常
如果想捕捉所有异常,只要捕捉Exception异常就行异常规格(exception specification)
在函数定义时可以声明异常规格。如果一个函数在异常规格中声明了non-RuntimeException异常,那么当调用这个函数时,就一定要捕捉异常规格中的non-RuntimeException异常。
1. import java.lang.RuntimeException;
2. import java.lang.NullPointerException;
3. import java.sql.SQLException;
4. class TestException{
5.  异常规格中声明将抛出RuntimeException异常
6. public void testRuntime() throws RuntimeException {}
7. //(异常规格中声明将抛出NullPointerException异常
8. public void testNullPointer() throws NullPointerException {}
9. 异常规格中声明将抛出non-RuntimeException异常

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
父类异常应该往后面放,ArithmeticException  ,ArithmeticException 是Exception的子类。所以编译时会报错
回复 使用道具 举报
首先你这段代码肯定编译通不过,因为Exception是ArithmeticException与ArrayIndexOutOfBoundsException的父类,所以,一旦div方法抛出异常,它会顺着catch块去找,既然catch(Exception e)满足条件(多态特性),那么后面的两个catch永远得不到执行,因此编译报错。

从名称上也可以看出ArithmeticException与ArrayIndexOutOfBoundsException是Exception的子类,因为一般Exception的子类名均以Exception结尾。

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

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
何洪森 黑马帝 2012-2-10 22:02:22
9#
你要是想捕获更精确的异常,就如你说的ArithmeticException,ArrayIndexOutOfBoundsException
这两个异常,那就不能先catch(Exception e)了,因为它是一个最大的异常,在它后面的异常
就会被忽略了,如果你要是想分别捕获,应该把catch(Exception e)放最后面。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
戴振良 黑马帝 2012-2-10 21:21:59
8#
本帖最后由 戴振良 于 2012-2-10 21:23 编辑

你总共使用了3个catch,因为Exception是所有异常的父类,所以不管发生什么异常都属于Exception异常,第一个catch的代码块就被执行了,后面的两个catch语句就不可能会被执行,那么就等于是白写这些代码,所以这个语法肯定是错误的,因为你这样写就没有意义了。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
李泽霖 黑马帝 2012-2-10 21:21:13
7#

class Demo
{
        int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException
        {

                int[] arr = new int[a];

                System.out.println(arr[4]);

                return a/b;
        }
}


class  ExceptionDemo2
{
        public static void main(String[] args) //throws Exception
        {
                Demo d = new Demo();
                try
                {
                        int x = d.div(5,0);
                        System.out.println("x="+x);
                }
               
                catch(Exception e)
                {
                        System.out.println("hahah:"+e.toString());
                }
                catch (ArithmeticException e)
                {
                        System.out.println(e.toString());
                }
                                 catch (ArrayIndexOutOfBoundsException e)
                {
                        System.out.println(e.toString());
                }
                                 catch (NullPointerException e)
                {
                        System.out.println(e.toString());
                }
                                 catch (ClassCastException e)
                {
                        System.out.println(e.toString());
                }
                       
       
              
               
               
                              

                System.out.println("over");

        }
}
//抛出4个异常


从上面的修改过的例子可以看出先抛父异常,所定义的子异常都会显示出来,因为他们是继承关系,所以条件符合,都会抛出

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
class Demo//该程序编译失败。原因:多个catch情况下,异常的父类写在了异常子类的前面。
{
        int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException
        {

                int[] arr = new int[a];

                System.out.println(arr[4]);

                return a/b;
        }
}


class  ExceptionDemo2
{
        public static void main(String[] args) //throws Exception
        {
                Demo d = new Demo();
                try
                {
                        int x = d.div(5,0);
                        System.out.println("x="+x);
                }
               
                catch(Exception e)
                {
                        System.out.println("hahah:"+e.toString());
                }
                catch (ArithmeticException e)
                {
                        System.out.println(e.toString());
                }
                catch (ArrayIndexOutOfBoundsException e)
                {
                        System.out.println(e.toString());
                }
               
                                

                System.out.println("over");

        }
}
/*在异常中可以灵活使用,可以将两种异常子类ArithmeticException,ArrayIndexOutOfBoundsException
都通过Exception接收并且处理。此程序在正常情况下就出现两种异常一个数组角标越界异常,一个运行时异常
,这样如果有针对这两个异常的处理就可以省略父类的异常。当然也直接用父类异常顶替两个子类异常。
*/

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
首先你的catch语句写的就有问题,捕获的异常,父类异常应该往后放
顺序应该是:
                  catch (ArithmeticException e)
                {
                        System.out.println(e.toString());
                }
                catch (ArrayIndexOutOfBoundsException e)
                {
                        System.out.println(e.toString());
                }
                catch(Exception e)
                {
                        System.out.println("hahah:"+e.toString());
                }


再者就是你得程序就没有角标越界异常(ArrayIndexOutOfBoundsException ),根本不用捕获抛出。
你数组定义的是int[] arr = new int[5];  数组有五个元素, arr[4]正好去的是最后一个元素。

代码修改后是:

class Demo
{
        int div(int a,int b)throws ArithmeticException{

                int[] arr = new int[a];

                System.out.println(arr[4]);

                return a/b;
        }
}


public class  ExceptionDemo2
{
        public static void main(String[] args)
        {
                Demo d = new Demo();
                try
                {
                        int x = d.div(5,0);
                        System.out.println("x="+x);
                }
               
                catch(ArithmeticException e)
                {
                        System.out.println("hahah:"+e.toString());
                }
               
                                

                System.out.println("over");

        }
}

评分

参与人数 1技术分 +2 收起 理由
唐秀启 + 2 赞一个!

查看全部评分

回复 使用道具 举报
把“catch(Exception e)”放在那两个异常的后面,因Exception 是总的异常,包括那两个异常。
回复 使用道具 举报
Exception  应该放到最后捕捉。Exception   已经包含了 ArrayIndexOutOfBoundsException 和ArithmeticException ,如果按照楼主的代码的话编译器会觉得多此一举。我们可以写多个catch语句,但是不能将父类型的exception的位置写在子类型的excepiton之前,因为这样父类型肯定先于子类型被匹配,所有子类型就成为可有可无的代码,编译器报错

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
Exception  有这个 后面的 ArithmeticException  ,ArithmeticException 的就不要了,后两个是前一个子类,父类异常与子类异常不要共存!

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马