8142493: Utility methods to check indexes and ranges doesn't specify behavior when function produces null
authorpsandoz
Tue, 17 Nov 2015 14:11:46 +0100
changeset 33844 c81ff6d8588d
parent 33843 8fdd836f35bc
child 33845 8b8ce7a896fd
8142493: Utility methods to check indexes and ranges doesn't specify behavior when function produces null Reviewed-by: lancea, rriggs, mchung
jdk/src/java.base/share/classes/java/util/Objects.java
jdk/test/java/util/Objects/CheckIndex.java
--- a/jdk/src/java.base/share/classes/java/util/Objects.java	Tue Nov 17 14:11:42 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Objects.java	Tue Nov 17 14:11:46 2015 +0100
@@ -352,15 +352,16 @@
      * @param b the second out of bound value
      * @param oobe the exception mapping function that when applied with out of
      *        bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
+     *        then, it is as if an exception mapping function was supplied that
      *        returns {@link IndexOutOfBoundsException} for any given arguments.
      * @return the runtime exception
      */
     private static RuntimeException outOfBounds(
             int a, int b, BiFunction<Integer, Integer, ? extends RuntimeException> oobe) {
-        return oobe == null
-               ? new IndexOutOfBoundsException(a, b)
-               : oobe.apply(a, b);
+        RuntimeException e = oobe == null
+                             ? null : oobe.apply(a, b);
+        return e == null
+               ? new IndexOutOfBoundsException(a, b) : e;
     }
 
     /**
@@ -408,8 +409,10 @@
      * @param length the upper-bound (exclusive) of the range
      * @param oobe the exception mapping function that when applied with out
      *        of bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
-     *        returns {@link IndexOutOfBoundsException} for any given arguments.
+     *        or returns {@code null} then, it is as if an exception mapping
+     *        function was supplied that returns
+     *        {@link IndexOutOfBoundsException} for any given arguments.
+     *        Exceptions thrown by the function are relayed to the caller.
      * @return {@code index} if it is within bounds of the range
      * @throws T if the {@code index} is out of bounds, then a runtime exception
      *         is thrown that is the result of applying the out of bounds
@@ -484,8 +487,10 @@
      * @param length the upper-bound (exclusive) the range
      * @param oobe the exception mapping function that when applied with out
      *        of bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
-     *        returns {@link IndexOutOfBoundsException} for any given arguments.
+     *        or returns {@code null} then, it is as if an exception mapping
+     *        function was supplied that returns
+     *        {@link IndexOutOfBoundsException} for any given arguments.
+     *        Exceptions thrown by the function are relayed to the caller.
      * @return {@code fromIndex} if the sub-range within bounds of the range
      * @throws T if the sub-range is out of bounds, then a runtime exception is
      *         thrown that is the result of applying the out of bounds arguments
@@ -553,8 +558,10 @@
      * @param length the upper-bound (exclusive) of the range
      * @param oobe the exception mapping function that when applied with out
      *        of bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
-     *        returns {@link IndexOutOfBoundsException} for any given arguments.
+     *        or returns {@code null} then, it is as if an exception mapping
+     *        function was supplied that returns
+     *        {@link IndexOutOfBoundsException} for any given arguments.
+     *        Exceptions thrown by the function are relayed to the caller.
      * @return {@code fromIndex} if the sub-range within bounds of the range
      * @throws T if the sub-range is out of bounds, then a runtime exception is
      *         thrown that is the result of applying the out of bounds arguments
--- a/jdk/test/java/util/Objects/CheckIndex.java	Tue Nov 17 14:11:42 2015 +0100
+++ b/jdk/test/java/util/Objects/CheckIndex.java	Tue Nov 17 14:11:46 2015 +0100
@@ -25,7 +25,7 @@
  * @test
  * @summary IndexOutOfBoundsException check index tests
  * @run testng CheckIndex
- * @bug 8135248
+ * @bug 8135248 8142493
  */
 
 import org.testng.annotations.DataProvider;
@@ -54,6 +54,15 @@
         };
     }
 
+    static BiFunction<Integer, Integer, AssertingOutOfBoundsException> assertingOutOfBoundsReturnNull(
+            int expFromIndex, int expToIndexOrSizeOrLength) {
+        return (fromIndex, toIndexOrSizeorLength) -> {
+            assertEquals(fromIndex, Integer.valueOf(expFromIndex));
+            assertEquals(toIndexOrSizeorLength, Integer.valueOf(expToIndexOrSizeOrLength));
+            return null;
+        };
+    }
+
     static final int[] VALUES = {0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, -1, Integer.MIN_VALUE + 1, Integer.MIN_VALUE};
 
     @DataProvider
@@ -95,6 +104,8 @@
         check.accept(AssertingOutOfBoundsException.class,
                      () -> Objects.checkIndex(index, length, assertingOutOfBounds(index, length)));
         check.accept(IndexOutOfBoundsException.class,
+                     () -> Objects.checkIndex(index, length, assertingOutOfBoundsReturnNull(index, length)));
+        check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkIndex(index, length, null));
         check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkIndex(index, length));
@@ -140,6 +151,8 @@
         check.accept(AssertingOutOfBoundsException.class,
                      () -> Objects.checkFromToIndex(fromIndex, toIndex, length, assertingOutOfBounds(fromIndex, toIndex)));
         check.accept(IndexOutOfBoundsException.class,
+                     () -> Objects.checkFromToIndex(fromIndex, toIndex, length, assertingOutOfBoundsReturnNull(fromIndex, toIndex)));
+        check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromToIndex(fromIndex, toIndex, length, null));
         check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromToIndex(fromIndex, toIndex, length));
@@ -192,6 +205,8 @@
         check.accept(AssertingOutOfBoundsException.class,
                      () -> Objects.checkFromIndexSize(fromIndex, size, length, assertingOutOfBounds(fromIndex, size)));
         check.accept(IndexOutOfBoundsException.class,
+                     () -> Objects.checkFromIndexSize(fromIndex, size, length, assertingOutOfBoundsReturnNull(fromIndex, size)));
+        check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromIndexSize(fromIndex, size, length, null));
         check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromIndexSize(fromIndex, size, length));