Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8268770

(JEP-356) - RandomGenerator spec implementation requirements tightly coupled to JDK internal classes

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 17
    • core-libs
    • None
    • source
    • minimal
    • Documentation only
    • Java API
    • SE

      Summary

      Specific @implSpec in the RandomGenerator javadoc make reference to code that is internal to the JDK.

      Problem

      Making these references a spec requirement contravene JCK rules.

      Solution

      Change @implSpec in these cases to @implNote. In the case of RandomGeneratorFactory::all(0), remove the phrase "or are not properly configured"

      Specification

      diff --git a/src/java.base/share/classes/java/util/random/RandomGenerator.java b/src/java.base/share/classes/java/util/random/RandomGenerator.java
      index 0080a897892..9feff713192 100644
      --- a/src/java.base/share/classes/java/util/random/RandomGenerator.java
      +++ b/src/java.base/share/classes/java/util/random/RandomGenerator.java
      @@ -516,9 +516,10 @@ public interface RandomGenerator {
            * @throws IllegalArgumentException if {@code bound} is not
            *         both positive and finite
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextFloat boundedNextFloat}(this, bound).
      +     * @implSpec The default implementation checks that {@code bound} is a
      +     * positive finite float. Then invokes {@code nextFloat()}, scaling
      +     * the result so that the final result lies between {@code 0.0f} (inclusive)
      +     * and {@code bound} (exclusive).
            */
           default float nextFloat(float bound) {
               RandomSupport.checkBound(bound);
      @@ -540,9 +541,11 @@ public interface RandomGenerator {
            *         or {@code bound} is not finite, or {@code origin}
            *         is greater than or equal to {@code bound}
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextFloat boundedNextFloat}(this, bound).
      +     * @implSpec The default implementation checks that {@code origin} and
      +     * {@code bound} are positive finite floats. Then invokes
      +     * {@code nextFloat()}, scaling and translating the result so that the final
      +     * result lies between {@code origin} (inclusive) and {@code bound}
      +     * (exclusive).
            */
           default float nextFloat(float origin, float bound) {
               RandomSupport.checkRange(origin, bound);
      @@ -577,9 +580,10 @@ public interface RandomGenerator {
            * @throws IllegalArgumentException if {@code bound} is not
            *         both positive and finite
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextDouble boundedNextDouble}(this, bound).
      +     * @implSpec The default implementation checks that {@code bound} is a
      +     * positive finite double. Then invokes {@code nextDouble()}, scaling
      +     * the result so that the final result lies between {@code 0.0} (inclusive)
      +     * and {@code bound} (exclusive).
            */
           default double nextDouble(double bound) {
               RandomSupport.checkBound(bound);
      @@ -601,9 +605,11 @@ public interface RandomGenerator {
            *         or {@code bound} is not finite, or {@code origin}
            *         is greater than or equal to {@code bound}
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextDouble boundedNextDouble}(this, bound).
      +     * @implSpec The default implementation checks that {@code origin} and
      +     * {@code bound} are positive finite doubles. Then calls
      +     * {@code nextDouble()}, scaling and translating the result so that the final
      +     * result lies between {@code origin} (inclusive) and {@code bound}
      +     * (exclusive).
            */
           default double nextDouble(double origin, double bound) {
               RandomSupport.checkRange(origin, bound);
      @@ -627,16 +633,20 @@ public interface RandomGenerator {
            * Returns a pseudorandomly chosen {@code int} value between zero
            * (inclusive) and the specified bound (exclusive).
            *
      -     * @param bound the upper bound (exclusive) for the returned value. Must be positive.
      +     * @param bound the upper bound (exclusive) for the returned value.
      +     * Must be positive.
            *
            * @return a pseudorandomly chosen {@code int} value between
            *         zero (inclusive) and the bound (exclusive)
            *
            * @throws IllegalArgumentException if {@code bound} is not positive
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextInt boundedNextInt}(this, bound).
      +     * @implSpec The default implementation checks that {@code bound} is a
      +     * positive {@code int}. Then invokes {@code nextInt()}, limiting the result
      +     * to be greater than or equal zero and less than {@code bound}. If {@code bound}
      +     * is a power of two then limiting is a simple masking operation. Otherwise,
      +     * the result is re-calculated by invoking {@code nextInt()} until the
      +     * result is greater than or equal zero and less than {@code bound}.
            */
           default int nextInt(int bound) {
               RandomSupport.checkBound(bound);
      @@ -657,9 +667,13 @@ public interface RandomGenerator {
            * @throws IllegalArgumentException if {@code origin} is greater than
            *         or equal to {@code bound}
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound(long) checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextInt(RandomGenerator, int) boundedNextInt}(this, bound).
      +     * @implSpec The default implementation checks that {@code origin} and
      +     * {@code bound} are positive {@code ints}. Then invokes {@code nextInt()},
      +     * limiting the result to be greater that or equal {@code origin} and less
      +     * than {@code bound}. If {@code bound} is a power of two then limiting is a
      +     * simple masking operation. Otherwise, the result is re-calculated  by
      +     * invoking {@code nextInt()} until the result is greater than or equal
      +     * {@code origin} and less than {@code bound}.
            */
           default int nextInt(int origin, int bound) {
               RandomSupport.checkRange(origin, bound);
      @@ -678,16 +692,21 @@ public interface RandomGenerator {
            * Returns a pseudorandomly chosen {@code long} value between zero
            * (inclusive) and the specified bound (exclusive).
            *
      -     * @param bound the upper bound (exclusive) for the returned value.  Must be positive.
      +     * @param bound the upper bound (exclusive) for the returned value.
      +     * Must be positive.
            *
            * @return a pseudorandomly chosen {@code long} value between
            *         zero (inclusive) and the bound (exclusive)
            *
            * @throws IllegalArgumentException if {@code bound} is not positive
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextLong boundedNextLong}(this, bound).
      +     * @implSpec The default implementation checks that {@code bound} is a
      +     * positive  {@code long}. Then invokes {@code nextLong()}, limiting the
      +     * result to be greater than or equal zero and less than {@code bound}. If
      +     * {@code bound} is a power of two then limiting is a simple masking
      +     * operation. Otherwise, the result is re-calculated by invoking
      +     * {@code nextLong()} until the result is greater than or equal zero and
      +     * less than {@code bound}.
            */
           default long nextLong(long bound) {
               RandomSupport.checkBound(bound);
      @@ -708,9 +727,13 @@ public interface RandomGenerator {
            * @throws IllegalArgumentException if {@code origin} is greater than
            *         or equal to {@code bound}
            *
      -     * @implSpec The default implementation simply calls
      -     * {@link RandomSupport#checkBound checkBound}(bound) and then
      -     * {@link RandomSupport#boundedNextLong boundedNextLong}(this, bound).
      +     * @implSpec The default implementation checks that {@code origin} and
      +     * {@code bound} are positive {@code longs}. Then invokes {@code nextLong()},
      +     * limiting the result to be greater than or equal {@code origin} and less
      +     * than {@code bound}. If {@code bound} is a power of two then limiting is a
      +     * simple masking operation. Otherwise, the result is re-calculated by
      +     * invoking {@code nextLong()} until the result is greater than or equal
      +     * {@code origin} and less than {@code bound}.
            */
           default long nextLong(long origin, long bound) {
               RandomSupport.checkRange(origin, bound);
      @@ -892,10 +915,6 @@ public interface RandomGenerator {
                * Returns an instance of {@link SplittableGenerator} that utilizes the
                * {@code name} <a href="package-summary.html#algorithms">algorithm</a>.
                *
      -         * @implNote Availability is determined by RandomGeneratorFactory using the
      -         * service provider API to locate implementations of the RandomGenerator
      -         * interface and filtering on the SplittableGenerator interface.
      -         *
                * @param name  Name of random number generator
                *              <a href="package-summary.html#algorithms">algorithm</a>
                *
      diff --git a/src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java b/src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java
      index 2ed63f2455d..552d7b03d53 100644
      --- a/src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java
      +++ b/src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java
      @@ -374,7 +374,7 @@ public final class RandomGeneratorFactory<T extends RandomGenerator> {
           /**
            * Returns a non-empty stream of available {@link RandomGeneratorFactory RandomGeneratorFactory(s)}.
            *
      -     * RandomGenerators that are marked as deprecated or are not properly configured are not included in the result.
      +     * RandomGenerators that are marked as deprecated are not included in the result.
            *
            * @implSpec Availability is determined by RandomGeneratorFactory using the service provider API
            * to locate implementations of the RandomGenerator interface.

            jlaskey Jim Laskey
            kganapureddy Krushnareddy Ganapureddy
            Joel Borggrén-Franck (Inactive), Roger Riggs
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: