使用instanceof和cast时获取原始Java类

时间:2013-01-25 18:39:37

标签: java exception casting instanceof

首先,对于那些憎恨,厌恶和鄙视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,我也没有看到任何其他方式来实现这种逻辑(但无论如何,请提出建议......只要他们不穿不涉及对instanceofMessageMessageContainer方法进行更改!)。

但即使使用handle(MessageContainer),这段代码甚至可以工作?从instanceof中提取Exception之后,我认为Message中的任何一个都不会触发,因为它会转换为instanceof,无法检测它是ExceptionBuzzException等。我有什么选择?提前谢谢。

3 个答案:

答案 0 :(得分:3)

此代码将按预期工作。在运行时期间,instanceof语句将比较exc的实际类型,而不仅仅假设这只是Exception。如果唯一有效的陈述是exc instanceof Exceptioninstanceof将毫无价值:)

另一种解决方案(我会避免使用)是比较完全限定的类名:

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()来管理您无法更改的异常类。