【问题标题】:Obtaining the original Java class while using instanceof and casting在使用 instanceof 和强制转换时获取原始 Java 类
【发布时间】:2023-03-28 20:29:01
【问题描述】:

首先,对于那些厌恶、厌恶和鄙视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 被传递给 MessageContainer 而不是可注入的 Message 实例这一事实。

所以,即使我真的不喜欢使用instanceof,我也看不出有任何其他方法可以完成这个逻辑(但无论如何,请提出建议......只要他们不涉及更改MessageMessageContainerhandle(MessageContainer) 方法!)。

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

【问题讨论】:

    标签: java exception casting instanceof


    【解决方案1】:

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

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

    String fqcn = exc.getClass().getName();
    
    if (fqcn.equals("com.foo.FizzException") {
        // etc.
    }
    

    【讨论】:

    • 最后一位不起作用,因为它将在编译时类型上调度,而不是在变量的运行时类型上。
    • +1 表示第一部分 -1 表示第二部分,它不起作用,正如 Nathan Hughes ^^ 所说。
    • @NathanHughes 是对的。我刚刚写了这个小测试程序:pastebin.com/TiZJXrXs 在所有四种情况下,它都会调用 Object 的方法。
    • 你说得对,我忘了这个。我从答案中删除了最后一部分。
    【解决方案2】:

    对异常的强制转换

    Exception exc = msg.getException();
    

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2010-10-03
        • 1970-01-01
        • 2015-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多