Java NoSuchMethodException代替返回null的目的是什么

Java NoSuchMethodException代替返回null的目的是什么,java,Java,在Java中,Foo.class.getMethod(“bar”)声明类型为NoSuchMethodException的已检查异常 这个例外的目的是什么?返回null是否足以表明未找到它?抛出异常会添加哪些信息或实用程序?除了强迫用户明确地意识到可能找不到它之外,这似乎是多余的。在Java中,当某些东西不存在时返回null,这是一种常见的模式,这似乎是一种主要的候选模式。那么这背后的原因是什么呢?Java API的设计者似乎区分了可以要求缺少的东西的情况和应该只要求存在的东西的情况 他们决定在映

在Java中,
Foo.class.getMethod(“bar”)
声明类型为
NoSuchMethodException
的已检查异常


这个例外的目的是什么?返回
null
是否足以表明未找到它?抛出异常会添加哪些信息或实用程序?除了强迫用户明确地意识到可能找不到它之外,这似乎是多余的。在Java中,当某些东西不存在时返回
null
,这是一种常见的模式,这似乎是一种主要的候选模式。那么这背后的原因是什么呢?

Java API的设计者似乎区分了可以要求缺少的东西的情况和应该只要求存在的东西的情况

他们决定在
映射中请求缺少的键是可以的,因为映射的内容是程序在运行时控制的。因此,类库的设计者认为在调用
Map.get
之前要求程序员检查值是否存在是不合理的,并决定返回
null

但是,类中的方法列表在特定运行期间始终保持静态,因此要求程序员仅对确实存在的方法调用
getMethod
。这种方法有两个后果:

  • 您可以请求多个方法,而无需检查每个方法-如果您有一个必须存在的方法列表,例如,在插件组件中,您可以获取它们的
    方法
    反射对象,而无需检查单个
    getMethod
    调用的返回值,以及
  • 当您不知道某个方法是否存在时,调用
    getMethods()
    -您仍然可以通过从
    对象获取完整列表来检查所有方法,而不知道它们的名称
下面是一个代码示例来说明第一点。当前API允许您编写以下内容:

class Plugin {
    private final Method init;
    private final Method start;
    private final Method stop;
    public Plugin(Class cl) throws PluginException, SecurityException {
        try {
            init = cl.getMethod("init");
            start = cl.getMethod("start");
            stop = cl.getMethod("stop");
        } catch (NoSuchMethodException ex) {
            throw new PluginException("Plugin is missing a required method", ex);
        }
    }
    ...
}
与此相反:

class Plugin {
    private final Method init;
    private final Method start;
    private final Method stop;
    public Plugin(Class cl) throws PluginException, SecurityException {
        init = cl.getMethod("init");
        if (init == null) {
            throw new PluginException("Plugin is missing init method");
        }
        start = cl.getMethod("start");
        if (start == null) {
            throw new PluginException("Plugin is missing start method");
        }
        stop = cl.getMethod("stop");
        if (stop == null) {
            throw new PluginException("Plugin is missing stop method");
        }
    }
    ...
}

你可能需要询问语言设计者
getMethod()
调用内部实现
getMethod0()
,并返回
null
,该
getMethod()
将其转换为异常。虽然这是一个有趣的问题,但我不确定这是一个合适的地方,因为它需要猜测和意见,除非碰巧有一位Java设计师来回答。简短回答:更好的调试信息。如果您认为在大多数情况下,没有任何好的方法可以从方法的失败中恢复,或者没有合理的方法来处理它,那么您应该抛出一个异常,尽可能多的信息来帮助调试。请求多个方法并捕获一次是我没有考虑过的一个很好的特性。但在我看来,这更像是一个方便的副作用,而不是设计的目的。