1

In Java, Foo.class.getMethod("bar") declares a checked exception of type NoSuchMethodException (among others).

What is the purpose of this exception? Isn't returning null sufficient to indicate that it was not found? What information or utility does throwing an exception add? Aside from forcing the user to explicitly be aware that it's possible for it to not be found, this seems superfluous. Returning null when something doesn't exist is a common pattern in Java, and this seems to be a prime candidate for that. So what was the reasoning behind this?

Ed Marty
  • 39,590
  • 19
  • 103
  • 156
  • 3
    Possible duplicate of [Should a retrieval method return 'null' or throw an exception when it can't produce the return value?](https://stackoverflow.com/questions/175532/should-a-retrieval-method-return-null-or-throw-an-exception-when-it-cant-prod) – Oleg Nov 01 '17 at 16:51
  • You'll probably have to ask the language designers. `getMethod()` calls an internal implementation `getMethod0()` and this DOES return `null` which `getMethod()` converts to an exception. While it's an interesting question, I'm not sure SO is the right place for it as it calls for speculation and opinion unless by chance one of the Java designers happens to answer. – Jim Garrison Nov 01 '17 at 16:51
  • Short answer: _much_ better debugging information. If you think in most cases there won't be any good way to recover from the failure of a method, or a reasonable way to handle it, then you should throw an exception with as much information as possible to help debugging. – Louis Wasserman Nov 01 '17 at 17:02

1 Answers1

1

It appears that the designers of Java APIs made a distinction between situations when it's OK to ask for something that is missing and situations when you are supposed to ask only for things that exist.

They decided that asking for a missing key in a Map is OK, because the content of a map is something your program controls at runtime. Therefore, designers of the class library decided that it is unreasonable to ask programmers to check if a value is present before calling Map.get, and decided to return null instead.

The list of methods in a class, however, remains static at all times during a particular run, so it becomes reasonable to ask programmers to call getMethod only for methods that do exist. There are two consequences to this approach:

  • You can request multiple methods without checking each one - if you have a list of methods that must exist, for example, in a plugin component, you can get their Method reflection objects without checking the return value of individual getMethod calls, and
  • When you do not know if a method exists, call getMethods() - You can still examine all methods without knowing their names by getting a full list from the Class object.

Here is a code example to illustrate the first point. Current API lets you write this:

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);
        }
    }
    ...
}

instead of this:

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");
        }
    }
    ...
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Requesting multiple methods and catching once is a nice feature I hadn't considered. But to me it *seems* more like a handy side-effect, rather than the purpose of the design. – Ed Marty Nov 01 '17 at 17:23