【问题标题】:Is it good programming to have a return type of Exception?有一个返回类型的异常是好的编程吗?
【发布时间】:2014-04-25 22:27:27
【问题描述】:

我在一个项目的用例中遇到了一个奇怪的情况:ESQL 正在调用一个 java 方法,向它发送一个字符串输入参数,该方法将解组,应用一些逻辑,然后存储来自解组对象的有用信息。因此,该方法必须要么抛出 JAXBException,要么使用 try catch 来处理可能的异常。

问题在于,ESQL 不能调用在签名中包含 throws 的 java 方法。但是,我们希望任何错误都回落到之前调用的 MBNode 上,以便在那里得到适当的处理,因此 trycatch 就不存在了。

让我震惊的是,嘿,当我们遇到问题时,不可能返回一种 Exception 类型,否则返回 null 吗?所以我写了一个简单的方法来做这件事,虽然我没有收到任何警告或错误,但从良好编程的意义上来说,这对我来说似乎是错误的。

例如:

public Exception doStuffAndCheckForErorrs(String inString)
{
    if(inString.equals(null))
    {
       return new Exception("Your string is null");
    }
    else
    return null;
}

但我只是觉得以这种方式做任何事情都很糟糕。

我愿意接受任何想法或不同的解决方案,尤其是如果有办法解决 ESQL 签名问题。

更新

添加关于为什么 ESQL 过程无法在签名中调用带有 throws 子句的 java 方法的参考。

摘自 CREATE PROCEDURE 语句部分下的This link

"您要调用的任何 Java 方法都必须具有以下基本签名: 公共静态() where 必须在 ESQL 到 Java 数据类型映射表中的 Java IN 数据类型列表中(不包括 REFERENCE 类型,它不允许作为返回值),或者 Java void 数据类型。参数数据类型也必须在 ESQL 到 Java 数据类型映射表中。此外,Java 方法的签名中不允许有异常 throws 子句。”

【问题讨论】:

  • 你为什么要这么做?只需添加null 支票即可。如果您真的想做这样的事情,请使用布尔标志。除非你真的有这样的要求,否则返回 Exception 似乎是个坏主意。
  • @AniketThakur 请阅读完整的问题/帖子。是的,我确实有这样的要求,否则我不会发布问题。
  • 如果您试图返回异常,请使用 throws 并让调用方法捕获异常
  • 我宁愿通过使用未经检查的(AKA 运行时)异常来解决 ESQL 的限制。

标签: java exception error-handling ibm-integration-bus extended-sql


【解决方案1】:

这实际上不是关于 Java 的问题,而是关于 ESQL 的问题。

ESQL 能够处理通过 JNI 向 ESQL 代码抛出的 Java 异常,您应该会收到 BIP2917 错误。

我最初虽然这可能是 ESQL 方法解析器的问题,但在 IIB v9 上我能够成功调用以下方法:

public static void sayHello() throws Exception{
  System.out.println("hello");
}

这让我觉得你的 ESQL 外部函数/过程定义可能有其他问题?

【讨论】:

  • BIP2917 也是一个可恢复的异常,因此它应该像运行时的​​任何其他异常一样表现jsut
  • 两者都有关系,因为由于 ESQL 强加于它的限制,java 方法需要调整。请参阅我的更新以获取更多信息。我想看看您用来调用该方法的 ESQL,因为它可能用于反对开发人员处理该方的参数。
  • CREATE FUNCTION callHello() LANGUAGE JAVA EXTERNAL NAME "com.ibm.broker.testing.Hello.SayHello";
  • 通过 CALL callHello() 调用;
【解决方案2】:

这里的重点是你不能声明一个异常会被抛出;您仍然可以抛出 RuntimeException - 无需添加 throws 子句。

因此,如果您将 JAXBException 包装到 RuntimeException 中,则可以根据您的要求抛出并处理它,而不会破坏任何一个要求。不知道我是否会这样做;我不想返回异常类型,因为它不打算用作返回码。

请特别确保这种处理问题的异步方式不会破坏 ESQL 库,因为您将绕过他们的部分代码,可能会导致部分代码挂起。

【讨论】:

    【解决方案3】:

    返回异常是“又快又脏”。它可能非常强大和有用,但应尽可能避免。

    ESQL 中的调用是这样进行的,原因很充分,我不会在这里解释,但您可以使用方法定义中未出现的 RuntimeException 绕过它。

    【讨论】:

    • 你能在这里解释一下吗?像您建议的绕过是我正在寻找的,并且是首选解决方案,因为它不需要任何花哨的返回类型。如果您还可以详细说明为什么在 ESQL 中以这种方式进行调用,而不是“出于充分理由”,这将有助于更好地理解这种情况。
    • 有关此主题的更多信息,请查看this。 Grosso modo,它是数据类型的问题
    • 据我所知,它实际上适用于声明为抛出的异常,但我认为我应该扩展这里发生的事情。 ESQL 作为代理运行时的一部分在 C++/C 中实现。当您声明一个 externl 过程时,C++ 端使用 JNI 检查对象上可用的方法并找到与参数签名有效匹配的方法。据我从 JNI 文档中可以看出,没有办法检测“抛出”子句。我什至建议提出 PMR 来询问该限制是否真的适用。
    【解决方案4】:

    指定抛出异常的用例听起来可能写得不好。 抛出异常的业务或架构原因是什么?

    另一种方法是抛出 RuntimeException 或自定义子类。 这将允许您将其排除在方法签名之外。

    同样,用例似乎很奇怪。

    【讨论】:

      【解决方案5】:

      您的问题的直接答案是:

      不,返回类型为 Exception 的编程不好。 该机制旨在在出现问题时发生,因此返回类型 Exception 意味着您希望收到出现问题的后果。

      我知道你不能抛出异常,所以你应该用其他方法处理这个案例。

      当你想检查一些工作时,布尔方法很好:好 = 返回真,坏 = 返回假。

      Object 中值的封装是指当你想要获取工作的结果时:good = return new YourResultObject(val1, val2, ..., valx), bad = return null。

      【讨论】:

        【解决方案6】:

        您可以做的就是使用返回码,就像 C 程序用来报告它们的状态一样。

        或者,您也可以创建一个 Enum 并返回 Enum,如果您想区分不同类型的错误,两者都比布尔方法更灵活

            public Enum ReturnCodes {
                 SUCCESS,
                 NULLSTRING,
                 ...,
                 OTHERERROR,
            }
        

        【讨论】:

        • 由于 ENUM 不支持作为 ESQL 过程中的 OUT 参数类型,这相当于仅使用 int。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-12
        • 1970-01-01
        • 2020-09-16
        • 2011-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多