5
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() {}
}

这不编译

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

该变量e似乎最终成为类型Exception而不是实际类型 - 这似乎是合乎逻辑的,因为在编译类型时编译器不知道将抛出哪种类型。但是,有没有一种方法可以在不使A&B都从某个公共基类派生或实现公共接口的情况下完成这项工作?

4

3 回答 3

4

不,因为 Java 不支持鸭子类型

执行 aninstanceof和 cast eto either AorB显然会起作用,但在这种情况下您可能想要做的是以编写两个 catch 块的传统方式进行。

我的意思是,这是有道理的,对吧?在您想平等对待不同类型的异常的情况下,多捕获是合适的。在这种情况下,行为可能会大不相同(即使方法名称相同)。

于 2014-10-17T09:20:31.653 回答
1

您应该只创建一个 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();
  }

然后,您可以像这样捕获 C:

try
{
  if(true)
    throw new A();
  if(true)
    throw new B();
}
catch( C e)
{
  e.doit();
}
于 2014-10-17T09:19:49.663 回答
1

如果不使用接口,我可以使用 instanceof 代替吗?有点乏味。顺便说一句,为什么不编写两个 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() {}
}

另一种方法是使用反射。

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() {}
}

界面可能会有所帮助。

于 2014-10-17T09:24:21.607 回答