commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Phil Steitz <>
Subject Re: [math] right way to throw IndexOutOfBoundsException?
Date Mon, 08 Aug 2011 20:29:00 GMT
On 8/8/11 12:55 PM, Luc Maisonobe wrote:
> Le 08/08/2011 21:25, Phil Steitz a écrit :
>> On 8/8/11 12:03 PM, Gilles Sadowski wrote:
>>> Hi.
>>>>> [...]
>>>>>>> Cases such as this would fall in the "illegal argument"
>>>>>>> category.
>>>>>>> Thus:
>>>>>>>    throw new OutOfRangeException(index, 0, parameters.length);
>>>>>>> or, to get a more detailed message,
>>>>>>>    OutOfRangeException e = new OutOfRangeException(index, 0,
>>>>>>> parameters.length);
>>>>>>>    e.addMessage(INDEX, index);
>>>>>>>    throw e;
>>>>>>> Of course, "OutOfRangeException" cannot inherit from both
>>>>>>> "IllegalArgumentException" and "IndexOutOfBoundsException"...
>>>>>> I thought about that, but would prefer to throw
>>>>>> ArrayIndexOutOfBoundsException because that is really what is
>>>>>> going
>>>>>> on and I would prefer to throw the standard exception. 
>>>>>> Ideally, I
>>>>>> would like to throw that with a message reporting the value
>>>>>> and the
>>>>>> length of the array.  So, there are three choices:
>>>>>> 0) throw AIOB with no message
>>>>>> 1) subclass and throw with localized message - my suggestion
>>>>>> above
>>>>>> 2) OutOfRangeException
>>>>>> I like 1) the best and since we have decided to deprecate the
>>>>>> MathRuntimeException, note that it applies to all of the other
>>>>>> standard exceptions generated by MathRuntimeException's
>>>>>> createXxx
>>>>>> methods that have not yet been subclassed.  I think we should
>>>>>> follow
>>>>>> the generally accepted practice to favor standard exceptions, so
>>>>>> that means we are going to have to create wrappers for all
>>>>>> that we
>>>>>> use.  I am willing to help with this.  In this case, I will
>>>>>> go ahead
>>>>>> and add the MathArrayIndexOutOfBoundsException that will be an
>>>>>> ArrayIndexOutOfBoundsException if others are OK with this.  
>>>>>> Note
>>>>>> that doing this will allow us to handle situations where IAE
>>>>>> is not
>>>>>> appropriate (essentially why AIOB does not itself extend IAE).
>>>>> As I understand it, AIOB is a low-level exception that is
>>>>> thrown by the JVM
>>>>> checking an array access:
>>>>> ---CUT---
>>>>>    i = 3;
>>>>>    double a = arr[i]; //<--- can throw AIOB
>>>>> ---CUT---
>>>>> However, I don't see how a user code can be similar to this:
>>>>> When you check
>>>>> the index in your above code, you didn't try to access the
>>>>> array yet. You've
>>>>> detected that it won't work because the index value is "out of
>>>>> range", thus,
>>>>> "illegal".
>>>> When we are about to access an array, we can perform the
>>>> check.  We
>>>> can either just allow the JVM to throw the RTE (essentially my
>>>> option 0) above) or provide some more context info to the user (my
>>>> option 1) or throw an entirely different exception (option 2).  It
>>>> is good to throw some kind of AIOB when that is in fact what is
>>>> going on, as it provides more context info than just "something is
>>>> out of range" (OutOfRangeException).
>>> As shown above, you can add as many items of context information
>>> as you want
>>> with the exception context. The example I've suggested above
>>> will create a
>>> message that will print something like:
>>>    OutOfRangeException: 3 out of [0, 2] range: index (3)
>>> I find this quite clear; but we can even add another
>>> "LocalizedFormats" like
>>> "ARRAY_INDEX" if you really need the above to read:
>>>    OutOfRangeException: 3 out of [0, 2] range: array index (3)
>>> However, the crux of my point is that the "array" part is an
>>> implementation
>>> detail. A user should not care that a sequence of data is stored
>>> in an array
>>> of primitives or in a "List" or a CM's "RealVector". The real
>>> info is that
>>> the index used to access the data must fall within a range; if
>>> not, it is
>>> "out of range".
>>> Then, what I was saying in the previous post is that we should
>>> not throw
>>> AIOB because we are not the JVM. In Java, that exception is a
>>> *result* of
>>> "calling" the [] operator. Your test happens before calling it;
>>> and an
>>> "OutOfRangeException" is as accurate as necessary but not more
>>> (so as not to
>>> leak about the internals of a class).
>> I can see that we are not going to agree on this.  I prefer standard
>> exceptions and it is generally accepted best practice to favor
>> them.  To say that only the JDK should throw JDK RTEs is silly,
>> IMO.  We are going to have the same problem with ConcurrentMod, IO,
>> EOF and the others currently created by MathRuntimeException.  Are
>> we going to try to shoehorn every use of any of these into some kind
>> of "some number too small" or other special [math] exceptions?  What
>> do others think about this?
> Well, I basically gave up on exceptions :-(
> Here are my views, but I would not enforce them anymore on anybody.
> I consider JDK exceptions could be used, and that we needed the
> localization (I know the view of everyone on this, so don't argue
> again). this was the reason for the createXxx exception, which had
> signatures corresponding to standard exceptions, and did subclass
> them with anonymous classes that override the JDK standard
> getMessage and getLocalizedMessage methods. This way, we combined
> both needs.

Well, I agree with your views and I am proposing that as a
compromise, we simply replace the createXxx methods in
MathRuntimeExceptions with exceptions like MathArithmeticException,
MathIllegalStateException, etc.  I am proposing in this case to add
MathArrayIndexOutOfBoundsException (extending AIOB so you can
advertise the real thing) and I will even volunteer to fill in the
remaining ones from createXxx so we don't have to argue about this
any more.

> Once again, this are only my own views. Do what you want with them.
> Luc
>> Phil
>>> Gilles
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail:
>>> For additional commands, e-mail:
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail:
>> For additional commands, e-mail:
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message