首先,对于那些憎恨,厌恶和鄙视instanceof
运营商的人,我理解你对它的关注,但我坚持使用它。那是因为我没有权力完全重构另一个开发团队设置项目的方式,所以除非我在这里缺少某些东西,否则我认为没有任何方法可以避免它。
我有一个无法更改的Java POJO,并允许您将Exception
设置为其属性之一:
public class Message {
private Exception exception;
public void setException(Exception exc) {
this.exception = exc;
}
}
同样,我无法更改此Message
课程。
我正在编写一个错误处理程序方法,它传递了MessageContainer
个实例,我需要逻辑来执行不同的操作,具体取决于容器的{{1}上设置的 type 异常}}:
Message
同样,我无法改变public class ErrorHandler {
public void handle(MessageContainer container) {
Message msg = container.getMessage();
Exception exc = msg.getException();
if(exc instanceof FizzException)
System.out.println("Do x");
else if(exc instanceof BuzzException)
System.out.println("Do y");
else
System.out.println("Do z");
}
}
传递ErrorHandler#handle
而不是注射MessageContainer
实例的事实。
所以,即使我真的不喜欢使用Message
,我也没有看到任何其他方式来实现这种逻辑(但无论如何,请提出建议......只要他们不穿不涉及对instanceof
,Message
或MessageContainer
方法进行更改!)。
但即使使用handle(MessageContainer)
,这段代码甚至可以工作?从instanceof
中提取Exception
之后,我认为Message
中的任何一个都不会触发,因为它会转换为instanceof
,无法检测它是Exception
,BuzzException
等。我有什么选择?提前谢谢。
答案 0 :(得分:3)
此代码将按预期工作。在运行时期间,instanceof
语句将比较exc
的实际类型,而不仅仅假设这只是Exception
。如果唯一有效的陈述是exc instanceof Exception
,instanceof
将毫无价值:)
另一种解决方案(我会避免使用)是比较完全限定的类名:
String fqcn = exc.getClass().getName();
if (fqcn.equals("com.foo.FizzException") {
// etc.
}
答案 1 :(得分:1)
上的强制转换
Exception exc = msg.getException();
不会删除异常运行时类型。它只是将它转换为基类型。 instanceof
仍然可以使用。但是,如果您的FizzException扩展了BuzzException,那么您将需要以其他顺序执行instanceof
检查。即先检查派生类型最多。
否则,它将进入基类检查子句而不是派生子句。
答案 2 :(得分:1)
目前尚不清楚你想要什么。如果异常全部“给定”并且您无法更改其实现,那么您可以使用exception.getClass()。getName()来获取类名,并且可以在表中查找或者选择您的课程行动。
如果可以更改许多异常实现,那么它们都会实现一个提供“functional()”方法或其他方法的接口。如果给定的Exception对象为instanceof MyFunctionalityInterface
,则转换为MyFunctionalityInterface并调用functionality()
以使其返回指导您的操作所需的信息。然后使用instanceof或getClass()。getName()来管理您无法更改的异常类。