RFR 8135248: Add utility methods to check indexes and ranges
forax at univ-mlv.fr
Tue Sep 22 06:08:19 UTC 2015
to summarize, there are a lot of codes that do bound checking in the JDK that report different kind of exceptions.
A way to retrofit most of then is to use a lambda to let the user code to choose its convention.
But because lambda creations are backed by invokedynamic, you can not retrofit
code that is used before the method handle mechanism is set up during the bootstraping of the JDK.
There are several kinds of bound checking, and i see no gain to force them to use the same function type.
Also, I have use a wildcard instead of a type variable given that it's an unchecked exception for the compiler.
For the simplest form of bound checking, 0 <= index < length, aka checkIndex, because there is only one index to report, i propose:
public static void checkIndex(int index, int length, IntFunction<? extends RuntimeException> exceptionCreator)
For the form of that uses a size, 0 <= index < size <= length, aka checkFromIndexSize, as you said, let's use a BiFunction<Integer, Integer, ...>,
public static void checkRange(int index, int size, int length, BiFunction<Integer, Integer, ? extends RuntimeException> exceptionCreator)
For the form that uses an offset, 0 <= index <= index + offset < length,
public static void checkRangeWithOffset(int index, int offset, int length, BiFunction<Integer, Integer, ? extends RuntimeException> exceptionCreator)
Also, the documentation should be clear that if a lambda captures values from the context, the performance will be worst than inlining the check by hand.
----- Mail original -----
> De: "Paul Sandoz" <paul.sandoz at oracle.com>
> Cc: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Envoyé: Lundi 21 Septembre 2015 17:46:07
> Objet: Re: RFR 8135248: Add utility methods to check indexes and ranges
> On 21 Sep 2015, at 16:45, Remi Forax <forax at univ-mlv.fr> wrote:
> > I agree with Stephen.
> > Calling the function interface with the name ...Exception seems very wrong
> > to me.
> Agreed, need to think of a better name. One solution is to remove it all
> together :-) see below.
> > The convention of ArrayIOOBE or StringIOOBE is to just report the bad index
> > with no further info,
> > currently with your code it's not possible to write
> > checkIndex(index, ArrayIndexOutOuBoundException::new).
> > so the functional interface for checkIndex should be int -> Object or long
> > -> Object if you change ArrayIOOBE and StringIOOBE to store a long.
> > This functional Interface already exists under the name
> > java.util.function.LongFunction.
> The friction here is trying to cater for the existing use-cases in the JDK,
> after a cursory 5 minute search you will find many conventions :-)
> From the use-cases i have looked at so far I believe it’s possible to support
> nearly all with BiFunction<Integer, Integer, RuntimeException> (i started
> out with that in mind), in some cases a process of elimination can be used
> for reporting. Other use-cases could be supported with capture.
> There is a use-case in AbstractStringBuilder that requires all three values,
> that is the only one i have found so far in the JDK. I would be interested
> to know if there are others and also if people are doing that in their own
> code too.
> I would be happy to sacrifice the use-case in AbstractStringBuilder for using
> BiFunction<Integer, Integer, RuntimeException>, and add appropriate
> constructors or factory methods on the common exception types for method ref
> > For the two other methods that checks several index, again the convention
> > is to report the bad index / size, so a LongFunction is enough too,
> > yes, it means that you can not check several index at once with things like
> > (a < 0) | (b < 0) but because the semantics you propose is different
> > from what is usually done, you will not be alble to use those methods
> > inside the JDK without introducing incompatibilities.
> > cheers,
> > Rémi
More information about the core-libs-dev