黑马程序员技术交流社区

标题: 一个不理解的异常问题 [打印本页]

作者: 周磊    时间: 2012-9-1 15:24
标题: 一个不理解的异常问题
public class A {

        public static void main(String[] args) {
               
                try{
                        int x=4/0;
                }catch (Exception e) {
                        System.out.println(e.getMessage());
                }
               
        }
       
}

getMessage()方法是非静态方法,而e没有实例化,为什么可以调用?不理解
作者: 孙沛    时间: 2012-9-1 15:34
本帖最后由 孙沛 于 2012-9-1 15:36 编辑

抛出异常时,就是抛出了个异常的对象,已经实例化好了, e.getMessage() 就可以直接调用了
这个e类似于函数参数,是别人实例化好了才传递给你的。
public void get(Exception e) {
   e.getMessage()
}
作者: 周磊    时间: 2012-9-1 15:43
class B extends Exception{
        public B(){
                System.out.println("实例化异常对象");
        }
}

public class A {

        public static void main(String[] args) throws B {
               
        int x=4/0;
        }
       
}
这样它也没有B类的构造函数的输出语句,那它是在那儿实例化的呢?
作者: 王得新    时间: 2012-9-1 15:55
本帖最后由 王得新 于 2012-9-1 16:00 编辑

举一个相似的例子:
public class TestExceptionDemo
{
          void start(){}
          public static void main(String[] args)
         {
                         TestExceptionDemo     testDemo=new TestExceptionDemo();
                       try
                      {
                                  testDemo.start();//这里假设产生异常         
                                  //因为try{}中产生异常,系统就会收到由testDemo.start()产生的Exception 对象e(所以它生成了一个对象,然后该对
                                        调用Exception的父类Throwable中的getMessage()方法,注意,所有异常都是Throwable的子类),然后会将异常对象
                                        catch代码块处理
                                  //
                      }catch(Exception e){
                               Sysotem.out.println(e.getMessage());
                      }
         }
}


作者: 周磊    时间: 2012-9-1 17:44
我研究下,谢谢了
作者: 黑马张旭明    时间: 2012-9-1 18:14
public class A {

        public static void main(String[] args) {
               
                try{
                        int x=4/0;
                }catch (Exception e) {
                        System.out.println(e.getMessage());
      }
  }
}
     这段代码,当4/0时会抛出异常,抛出的是一个类型为ArithmeticException异常对象,在Catch的参数中赋给了他的父类Exception e,其实就是这样:Exception e = new ArithmeticException(); 父类引用指向子类对象的多态。
    接下来是楼主的代码:
class B extends Exception{
        public B(){
                System.out.println("实例化异常对象");
        }
}
public class A {

        public static void main(String[] args) throws B {
               
        int x=4/0;                            //这抛出的是ArithmeticException异常和B没关系
        }
}
当4/0时抛出的是ArithmeticException异常,在主函数上抛B异常是不会有B对象产生的,"throws B"这句换成IOException(IO流异常和除零也没什么关系)也是一样抛出ArithmeticException异常。
楼主的B是自定义异常,建议多看下这块,我模仿毕老师的重写了一下你的自定义异常B,4/0换成了在demo.div(4,0);方法中执行。
     class Demo
{
     int div(int a,int b)throws B
     {
         if(b==0)                                              //产生B类异常的条件
             throw new B();                                 //这里抛出B类异常对象
          return a/b;
     }
}
public class A
{
     public static void main(String[] args)
     {
          try
          {
             Demo demo = new Demo();
             demo.div(4,0);                               //这里产生了一个B类的异常对象,其实ArithmeticException也是在异常处产生对象
          }
         catch(B b)
         {
             System.out.print("B类异常");
         }
         catch(Exception e)
         {
              System.out.println(e);
         }
       }
}
class B extends Exception
{
    public B()
    {
        System.out.println("实例化异常对象");
    }
}
输出结果是:
实例化异常对象
B类异常
楼主对自定义异常的了解太少,所以用错方法证明异常是否产生异常了对象。自定义异常和系统异常不同,我目前了解的要通过throws+对象 才能产生。


作者: 周磊    时间: 2012-9-1 19:03
你那种写法我知道,但是我那种写法是直接把异常抛出,这个抛出到底抛出的是什么?有没有对异常进行实例化?
“Exception e = new ArithmeticException(); 父类引用指向子类对象的多态”你的意思是Exception e它写完整应该是Exception e = new ArithmeticException();?

作者: 黑马张旭明    时间: 2012-9-1 19:20
    你的那种写法没有产生异常对象,抛出是没有反应的,只是在函数上抛出了异常类,函数里却没有产生异常对象。
   Exception e = new ArithmeticException();只是在这里,这个抛出是当4/0时系统抛出一个ArithmeticException(既除数为零异常)类异常的对象,不实例化哪来对象,系统自己实例化了。这里Exception e只是为了方便接收所有Exception的子类异常。
   总之,函数里是抛出个异常的对象,catch(Exception e)里用Exception e接收。
作者: 周磊    时间: 2012-9-1 19:43
谢谢了,我懂你的意思,你的意思是系统帮我们实例化了,但是什么我们自己在catch(e)中直接传一个e( e 是Exception的实例 Exception e =  new Exception())不能编译通过,也就是说这儿只能由系统进行实例化
作者: 黑马--张帅    时间: 2012-9-1 23:08
各个异常都有名称,信息(程序出错的原因),出错的位置等向上抽取形成Throwable可抛类,每种类都是继承这个Throwable类。抛出异常时,实际上是抛出的这个异常类的对象,同时通过这个异常类的构造函数进行了初始化。如果抛出的异常时Exception类的子类的话,在catch里定义Exception e来接收这个异常的子类对象(实现了多态)被捕捉后直接执行catch的代码块,从而打印这个异常的信息。在你的程序中try{int x = 4/0}抛出了除数是0的异常是RuntimeException异常,在这里用Exception e捕捉不到程序直接结束,下面的输出语句是不会执行的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2