简体   繁体   English

捕获多个异常 - 在捕获的异常上调用Exception中不存在的方法

[英]Catching Multiple Exceptions - calling methods not present in Exception on the caught exception

public class try
{
    public static void main(String[] args)
    {
        try
        {
            if(true)
                throw new A();
            if(true)
                throw new B();
        }
        catch( A | B e)
        {
            e.doit();
        }
    }
}

class A extends Exception
{
    public void doit() {}
}

class B extends Exception
{
    public void doit() {}
}

This doesn't compile 这不编译

18: error: cannot find symbol
        e.doit();
         ^
symbol:   method doit()
location: variable e of type Exception

The variable e seems to end up as type Exception rather than the actual type - this seems logical because at compile type the compiler doesn't know what kind is going to be thrown. 变量e似乎最终是类型Exception而不是实际类型 - 这似乎是合乎逻辑的,因为在编译类型时编译器不知道将抛出什么类型。 However, is there a way to make this work without making A & B both derive from some common base class or implement a common interface? 但是,有没有办法使这个工作不使AB都从某个公共基类派生或实现一个通用接口?

Well no, because Java doesn't support duck typing . 不,因为Java不支持鸭子打字

Doing an instanceof and casting e to either A or B is obviously going to work, but what you probably want to do in this case is doing it in the traditional way of writing two catch blocks . 做一个instanceof并将e转换为AB显然会起作用,但在这种情况下你可能想做的是以传统的方式编写两个catch块

I mean, it makes sense, right? 我的意思是,这是有道理的,对吧? Multi-catch is appropriate in the case where you want to treat different kinds of exceptions equally . 如果您想要平等对待不同类型的异常,则多次捕获是合适的。 In this case, the behaviour can be drastically different (even if the methods are named the same). 在这种情况下,行为可能会大不相同(即使方法命名相同)。

You should just create a super class that both A and B extend, give that class an doIt() method, and then implement that method for both A and B, like this: 你应该创建一个A和B都扩展的超类,给该类一个doIt()方法,然后为A和B实现该方法,如下所示:

  class A extends C {
    public void doit() {
    }
  }

  class B extends C {
    public void doit() {
    }
  }

  abstract class C extends Exception {
    public abstract void doit();
  }

You can then catch C, like this: 然后您可以捕获C,如下所示:

try
{
  if(true)
    throw new A();
  if(true)
    throw new B();
}
catch( C e)
{
  e.doit();
}

If not using interface, can I use instanceof instead. 如果不使用接口,我可以使用instanceof。 A little tedious. 有点单调乏味。 BTW, why you don't write two catch block to catch the two exceptions separately. 顺便说一下,为什么你不写两个catch块来分别捕获这两个例外。

public class Try
{
    public static void main(String[] args)
    {
        try
        {
            if(true)
                throw new A();
            if(true)
                throw new B();
        }
        catch(A | B e)
        {
            if(e instanceof A){
                ((A) e).doit();             
            }else if (e instanceof B){
                ((B) e).doit();             
            }
        }
    }
}

class A extends Exception 
{
    public void doit() {}
}

class B extends Exception 
{
    public void doit() {}
}

Another way is using reflect. 另一种方法是使用反射。

package com.stackoverflow;

import java.lang.reflect.Method;

public class Try
{
    public static void main(String[] args) throws Exception
    {
        try
        {
            if(true)
                throw new A();
            if(true)
                throw new B();
        }
        catch(A | B e)
        {
            Class cls = e.getClass();  
            Method doit = cls.getMethod("doit");
            doit.invoke(e, null);
        }
    }
}

class A extends Exception
{
    public void doit() {}
}

class B extends Exception
{
    public void doit() {}
}

The interface may help. 界面可能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM