2

首先,对于那些憎恶、厌恶和鄙视instanceof运营商的人,我理解你对它的担忧,但我坚持使用它。那是因为我无权完全重构另一个开发团队设置项目的方式,所以除非我在这里遗漏了一些东西,否则我看不到任何避免它的方法。

我有一个无法更改的 Java POJO,并允许您将其设置Exception为属性之一:

public class Message {
    private Exception exception;

    public void setException(Exception exc) {
        this.exception = exc;
    }
}

同样,我不能改变这个Message类。

我正在编写一个传递实例的错误处理程序方法,并且我需要根据容器上设置的异常类型MessageContainer来执行不同操作的逻辑: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传递 aMessageContainer而不是可注入Message实例的事实。

所以,即使我真的不喜欢使用instanceof,我也看不到任何其他方式来完成这个逻辑(但无论如何,请提出建议......只要他们不涉及对MessageMessageContainer,或handle(MessageContainer)方法!)。

但即使使用 using instanceof,这段代码又是如何工作的?一旦你将 s 拉出ExceptionMessage我认为任何instanceofs 都不会触发,因为它会转换为Exception,无法检测它是否是BuzzException,FizzException等。我在这里有什么选择?提前致谢。

4

3 回答 3

3

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

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

String fqcn = exc.getClass().getName();

if (fqcn.equals("com.foo.FizzException") {
    // etc.
}
于 2013-01-25T18:47:09.980 回答
1

强制转换为异常

Exception exc = msg.getException();

不会擦除异常运行时类型。它只是将其转换为基本类型。将instanceof仍然有效。但是,如果您的 FizzException 扩展了 BuzzException,那么您将需要instanceof按其他顺序进行检查。即首先检查最派生的类型。

否则,它将进入基类检查子句而不是派生子句。

于 2013-01-25T18:49:11.637 回答
1

不清楚你想要什么。如果异常都是“给定的”并且您无法更改它们的实现,那么您可以使用 exception.getClass().getName() 来获取类名,也许可以在表格或其他任何东西中查找以选择您的课程的行动。

如果您可以更改许多异常实现,则让它们都实现一个提供“功能()”方法或其他方法的接口。如果给定的 Exception 对象instanceof MyFunctionalityInterface随后被强制转换为 MyFunctionalityInterface 并调用functionality()以使其返回指导您的操作所需的信息。然后使用 instanceof 或 getClass().getName() 来管理无法更改的 Exception 类。

于 2013-01-25T19:04:12.283 回答