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
是从一些公共基类派生还是实现一个公共接口?
答案 0 :(得分:4)
不,因为Java不支持duck typing。
执行instanceof
并将e
投射到A
或B
显然会起作用,但在这种情况下您可能想要做的是编写两个catch块的传统方式。
我的意思是,这是有道理的,对吧?如果您想要处理不同类型的异常同等,则多次捕获是合适的。在这种情况下,行为可能会大不相同(即使方法命名相同)。
答案 1 :(得分: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();
}
答案 2 :(得分: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() {}
}
界面可能会有所帮助。