【问题标题】:Test a method if it would throw an exception or not without invoking it测试一个方法是否会抛出异常而不调用它
【发布时间】:2011-07-21 15:30:48
【问题描述】:

如何在不调用给定方法的情况下测试给定方法是否会抛出异常(取决于传递的对象)?

例如:

public static boolean isAllowed(SomeObject obj)
{
    try
    {
        myMethod(obj);
        return true;
    }
    catch(Exception ex)
    {
        return false;
    }
}

但是上面的方法会执行MyMethod(),我如何在java中实现呢?

编辑:

实际上,我想这样做是为了验证文件名。看到这个:Validate a file name on Windows

【问题讨论】:

  • 如果有源代码,您可以检查它,如果没有,请查看文档。如果两者都没有,则必须运行它。
  • 你不能用 Java 或我能想到的任何其他编程语言。也许在带有预处理器指令的 C/C++ 中。

标签: java exception


【解决方案1】:

正如其他人所说,通常不可能在不实际计算的情况下根据输入判断是否会引发异常。 Java 图灵完备,因此可以简化为halting problem。但是,您可以找到方法在运行时可以抛出的所有异常:

try {
    Method myMethod = this.getClass().getMethod("myMethod");
    System.out.println(Arrays.toString(myMethod.getExceptionTypes()));
} catch (NoSuchMethodException e) {}

【讨论】:

  • 这是否包括RuntimeException 和子类?可能不会,因为他们没有throws
  • @delnan 它确实只会报告方法签名中声明的检查异常。不过,这与 OP 所能做的一样好。考虑这段代码:void foo() { if ([condition requiring solution of the halting problem]) throw new Exception(); } 这样的方法会抛出异常吗? (有关一些相关信息,请参阅blogs.msdn.com/b/ericlippert/archive/2009/10/12/…。)
  • 我并不怀疑您的结论,即一般来说这是不可能的 - 这是毫无疑问的。我只是说“列在throws”不等于“实际上可以抛出”。
【解决方案2】:

您可以提供一个兄弟方法 isAllowed() 来显式测试导致异常的条件。

存在错误风险。这两种方法需要保持同步导致异常的条件。但是,正确编写测试方法通常是可行的。

来自 Joshua Bloch 的“Effective Java”:

具有“状态相关”方法的类,只能在以下情况下调用 某些不可预测的情况通常应该有一个单独的 "state-testing" 方法指示是否适合调用 状态相关的方法。

【讨论】:

    【解决方案3】:

    在一般情况下,您不能。例如,所讨论的方法可能使用随机数生成器来决定是否抛出异常。或者对于一个更现实的例子,如果有问题的方法尝试打开一个文件,那么您无法提前知道其他进程是否会在您尝试打开该文件之前删除该文件(这会导致异常)。

    Java 会告诉您它是否可能在编译时抛出异常(带有 throws 声明),但您无法确定它是否真的会在不执行的情况下抛出异常。

    【讨论】:

      【解决方案4】:

      您无法在编译时知道该方法是否会在运行时引发异常。

      如果你想知道方法是否可以抛出异常;只是不要将该方法包含在try-catch 块中。如果方法抛出异常,像 ecliple 这样的编辑器会清楚地显示编译错误。

      这就是你想要的;或者我误解了你的问题。

      【讨论】:

      • 你无法在编译时知道一个方法是否会在运行时抛出异常。只有未捕获的检查异常会引发编译器错误;未经检查的异常不会。
      【解决方案5】:

      显然,如果您不想调用但需要了解调用时的行为,那么您需要读取方法字节码。

      另一种选择是提供一个模拟类加载器并加载模拟类(从而实现无操作方法实现)。

      在一个功能齐全的宇宙中,上述方法将是一种合理的方法。鉴于它是 Java,如何保证和衡量副作用的问题仍有待回答。也许以上内容适用于您的具体情况,但对于一般情况,您实际上是在要求对 Java 字节码进行静态分析,而这本身可能是一个完整的研究领域。

      【讨论】:

        【解决方案6】:

        了解方法和有效参数比在调用之前盲目测试方法更好(这是不可能的)。

        在将参数传递给方法之前验证它们。这是一个简单的说明,其中传递 null 会导致异常:

        int getLength(String s)
        {
          return s.length();
        }
        
        void someMethod()
        {
          int len = -1;
          if (myString != null)
            len = getLength(myString);
        }
        

        【讨论】:

          【解决方案7】:

          创建一个 jUnit 测试

          http://www.junit.org/

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-04-18
            • 1970-01-01
            • 2010-12-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多