On Fri, Sep 14, 2012 at 10:41:50AM +0200, Luc Maisonobe wrote: > Le 14/09/2012 08:46, Sébastien Brisard a écrit : > > Hi Phil > > > >>> > >>> Back to square one, with 3 fully consistent alternatives: > >>> 1. CM to always check for null? Then "NullArgumentException" inheriting > >>> from > >>> "MathIllegalArgumentException" is fine because we promise to the user > >>> that > >>> no NPE will ever propagate through the CM layer. [Breaking that > >>> promise > >>> is a CM bug.] > >>> 2. CM to never check for null? Then we delete class > >>> "NullArgumentException". > >>> Users are warned by the general policy: "Do not pass null unless it is > >>> explicitly documented to be allowed." A bug will lead to the JVM > >>> raising > >>> a NPE. > >>> 3. CM to sometimes check for null? Then "NullArgumentException" should > >>> inherit from "NullPointerException" because the user will sometimes > >>> see > >>> "NullArgumentException" (when CM checks) and sometimes NPE (when CM > >>> does > >>> not check) and both should thus belong to the same hierarchy (from the > >>> user's point-of-view, there is no reason to handle them in different > >>> ways since it's the exact same bug). > >>> For the user, the consequence will be similar to alternative 2, with > >>> sometimes more information about the failure and sometimes > >>> (marginally) > >>> earlier detection. > >> > >> As stated above, my preference is > >> > >> 4. CM APIs *may* disallow nulls explicitly. When that is done, the > >> implementations *should* check parameters (as they *should* check > >> all other stated preconditions) and when preconditions are violated, > >> a MathIllegalArgumentException is thrown. I don't care whether or > >> not we keep NAE. If we drop it, we should make sure whatever > >> exception messages we used to use to indicate illegal null arguments > >> are still there. > >> > >> Phil > >> > > I like this option better than 3. So, I'll change my "vote" to option > > #2, and possibly option #4 as we will never agree on option #2.
Why is it better to throw MathIllegalArgumentException rather than NPE? > > My preferences are 4 or 3 with same preference level and 2 as a fallback > choice. For each option, I find the arguments are good, it's only a > matter or preference. Did everyone consider that Phil's alternative implies a behaviour that departs from the standard practice, a.o. * JDK (cf. quote in a previous post), * other libraries, e.g. Guava (cf. quote in a previous post), and * Java experts, e.g. Joshua Bloch[1] of throwing NPE when they encounter "null"? Doesn't anyone care about having a _reason_ for CM to behave differently? Don't you care that users will see different exceptions when the same problem is detected? Do you really like a policy that mandates different behaviours when "null" is disallowed implicitly vs explicitly (throwing NPE vs throwing MathRuntimeException)? [Pardon me, but IMHO this is nonsense.] After piling up arguments (_none_ of which have been addressed), I'm sorry to read that it would only be a "matter of preference"! [I should start a career as a writer if I'm able to express "preference" in so many words...] Actually, it's a matter of consistency ("same problem, same exception"). If nobody cares about improving CM's consistency, then indeed most of the discussions in which I take part are pointless. What is wrong with throwing NPE? [Alternative 3 is a compromise: it allows CM to fail as early as possible (which I thought was Phil's main point, as it was his only one, apart from "preference"), while being consistent ("same problem, same exception"), internally, externally, implicitly and explicitly. Alternative 4 is inconsistent ("same problem, different exceptions"); it's a truth, not a matter of taste.] Rather then being willingly stuck in a deadlock because only the weakest argument ("preference") is taken into account, wouldn't it be more reasonable to count all the arguments? Gilles [1] "Effective Java" (second edition). Excerpt from "Item 60": If a caller passes null in some parameter for which null values are prohibited, convention dictates that NullPointerException be thrown rather than IllegalArgumentException. > > Luc > > > > > Best regards, > > Sébastien > >>> > >>> Your alternative (sometimes check, sometimes not) is not fully consistent: > >>> * for the user: "In case of null reference, will I get a > >>> MathRuntimeException > >>> or a NPE?" > >>> * for the CM developer: "In which cases do I need to check for null?" > >>> > >>> Of course, I would reconsider if you could provide an actual example that > >>> would fail with all three alternatives which I suggested. If not, then > >>> it seems obvious that your alternative presents two defects that don't > >>> exist > >>> in any of those three. > >>> > >>> > >>> Gilles > >>> > >>>>>> [...] what is different about null arguments at the point of > >>>>>> method activation in an API that explicitly disallows them. > >>>>> The difference is that there is no need to tell the user what the > >>>>> problem > >>>>> is because the raised exception says it all: "You tried to use a null > >>>>> reference." [As said above, the only issue is _when_ the exception is > >>>>> triggered.] > >>>>> > >>>>> The policy mandates what is globally valid, e.g.: > >>>>> "If not specified otherwise, "null" is not allowed as an argument." > >>>>> Then, a user cannot complain about a NPE being propagated when he > >>>>> passed an > >>>>> invalid (null) argument. > >>>>> > >>>>> Finally, the case for "null" is also slightly peculiar (given the above) > >>>>> that it should not simply be bundled with the rationale "Fail early": > >>>>> Indeed > >>>>> "null" references always fail early (i.e. as soon as they are used). > >>>>> Deferring the check until it is done by the JVM will never entails the > >>>>> code > >>>>> to produce a wrong result _because_ of that null reference (it will just > >>>>> fail in the predictable way: NPE).[1] > >>>>> > >>>>> > >>>>> Gilles > >>>>> > >>>>> [1] Unlike in C, where an unitialized pointer would not necessarily > >>>>> crash > >>>>> the program, but _could_ make it behave erratically (including > >>>>> produce > >>>>> wrong results in a stealth way). > >>>>> > >>> --------------------------------------------------------------------- > >>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >>> For additional commands, e-mail: dev-h...@commons.apache.org > >>> > >>> > >> > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >> For additional commands, e-mail: dev-h...@commons.apache.org > >> > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > > For additional commands, e-mail: dev-h...@commons.apache.org > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org