This commit is contained in:
Jesper Wilhelmsson 2022-06-29 23:32:37 +00:00
commit 048bffad79
4 changed files with 114 additions and 14 deletions

View file

@ -2585,34 +2585,35 @@ public final class Locale implements Cloneable, Serializable {
/** /**
* {@code Builder} is used to build instances of {@code Locale} * {@code Builder} is used to build instances of {@code Locale}
* from values configured by the setters. Unlike the {@code Locale} * from values configured by the setters. Unlike the {@code Locale}
* constructors, the {@code Builder} checks if a value configured by a * constructors or {@code Locale.of()} factory methods,
* the {@code Builder} checks if a value configured by a
* setter satisfies the syntax requirements defined by the {@code Locale} * setter satisfies the syntax requirements defined by the {@code Locale}
* class. A {@code Locale} object obtained from a {@code Builder} is * class. A {@code Locale} object obtained from a {@code Builder} is
* well-formed and can be transformed to a well-formed IETF BCP 47 language tag * well-formed and can be transformed to a well-formed IETF BCP 47 language tag
* without losing information. * without losing information.
* *
* <p><b>Note:</b> The {@code Locale} class does not provide any * @implNote
* The {@code Locale} class does not provide any
* syntactic restrictions on variant, while BCP 47 requires each variant * syntactic restrictions on variant, while BCP 47 requires each variant
* subtag to be 5 to 8 alphanumerics or a single numeric followed by 3 * subtag to be 5 to 8 alphanumerics or a single numeric followed by 3
* alphanumerics. The method {@code setVariant} throws * alphanumerics. The method {@code setVariant} throws
* {@code IllformedLocaleException} for a variant that does not satisfy * {@code IllformedLocaleException} for a variant that does not satisfy
* this restriction. If it is necessary to support such a variant, use a * this restriction. If it is necessary to support such a variant, use
* Locale constructor. However, keep in mind that a {@code Locale} * {@link Locale#of(String, String, String)}. However, keep in mind that a {@code Locale}
* object obtained this way might lose the variant information when * object obtained this way might lose the variant information when
* transformed to a BCP 47 language tag. * transformed to a BCP 47 language tag.
* *
* <p>The following example shows how to obtain a {@code Locale} object * <p>The following example shows how to obtain a {@code Locale} object
* using a {@code Builder}. * using a {@code Builder}.
* <blockquote> * {@snippet lang=java :
* <pre> * Locale aLocale = new Locale.Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
* Locale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build(); * }
* </pre>
* </blockquote>
* *
* <p>Builders can be reused; {@code clear()} resets all * <p>Builders can be reused; {@code clear()} resets all
* fields to their default values. * fields to their default values.
* *
* @see Locale#forLanguageTag * @see Locale#forLanguageTag
* @see Locale#of(String, String, String)
* @since 1.7 * @since 1.7
*/ */
public static final class Builder { public static final class Builder {
@ -2763,11 +2764,12 @@ public final class Locale implements Cloneable, Serializable {
* the {@code Locale} class does not impose any syntactic * the {@code Locale} class does not impose any syntactic
* restriction on variant, and the variant value in * restriction on variant, and the variant value in
* {@code Locale} is case sensitive. To set such a variant, * {@code Locale} is case sensitive. To set such a variant,
* use a Locale constructor. * use {@link Locale#of(String, String, String)}.
* *
* @param variant the variant * @param variant the variant
* @return This builder. * @return This builder.
* @throws IllformedLocaleException if {@code variant} is ill-formed * @throws IllformedLocaleException if {@code variant} is ill-formed
* @see Locale#of(String, String, String)
*/ */
public Builder setVariant(String variant) { public Builder setVariant(String variant) {
try { try {

View file

@ -129,6 +129,11 @@ public class Random implements RandomGenerator, java.io.Serializable {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public boolean isDeprecated() {
return generator.isDeprecated();
}
@Override @Override
public void nextBytes(byte[] bytes) { public void nextBytes(byte[] bytes) {
this.generator.nextBytes(bytes); this.generator.nextBytes(bytes);
@ -144,11 +149,26 @@ public class Random implements RandomGenerator, java.io.Serializable {
return this.generator.nextInt(bound); return this.generator.nextInt(bound);
} }
@Override
public int nextInt(int origin, int bound) {
return generator.nextInt(origin, bound);
}
@Override @Override
public long nextLong() { public long nextLong() {
return this.generator.nextLong(); return this.generator.nextLong();
} }
@Override
public long nextLong(long bound) {
return generator.nextLong(bound);
}
@Override
public long nextLong(long origin, long bound) {
return generator.nextLong(origin, bound);
}
@Override @Override
public boolean nextBoolean() { public boolean nextBoolean() {
return this.generator.nextBoolean(); return this.generator.nextBoolean();
@ -159,16 +179,46 @@ public class Random implements RandomGenerator, java.io.Serializable {
return this.generator.nextFloat(); return this.generator.nextFloat();
} }
@Override
public float nextFloat(float bound) {
return generator.nextFloat(bound);
}
@Override
public float nextFloat(float origin, float bound) {
return generator.nextFloat(origin, bound);
}
@Override @Override
public double nextDouble() { public double nextDouble() {
return this.generator.nextDouble(); return this.generator.nextDouble();
} }
@Override
public double nextDouble(double bound) {
return generator.nextDouble(bound);
}
@Override
public double nextDouble(double origin, double bound) {
return generator.nextDouble(origin, bound);
}
@Override
public double nextExponential() {
return generator.nextExponential();
}
@Override @Override
public double nextGaussian() { public double nextGaussian() {
return this.generator.nextGaussian(); return this.generator.nextGaussian();
} }
@Override
public double nextGaussian(double mean, double stddev) {
return generator.nextGaussian(mean, stddev);
}
@Override @Override
public IntStream ints(long streamSize) { public IntStream ints(long streamSize) {
return this.generator.ints(streamSize); return this.generator.ints(streamSize);
@ -1066,7 +1116,7 @@ public class Random implements RandomGenerator, java.io.Serializable {
return AbstractSpliteratorGenerator.doubles(this); return AbstractSpliteratorGenerator.doubles(this);
} }
/** /**
* Returns a stream producing the given {@code streamSize} number of * Returns a stream producing the given {@code streamSize} number of
* pseudorandom {@code double} values, each conforming to the given origin * pseudorandom {@code double} values, each conforming to the given origin
* (inclusive) and bound (exclusive). * (inclusive) and bound (exclusive).
@ -1076,7 +1126,7 @@ public class Random implements RandomGenerator, java.io.Serializable {
* @param randomNumberBound the bound (exclusive) of each random value * @param randomNumberBound the bound (exclusive) of each random value
* @return a stream of pseudorandom {@code double} values, * @return a stream of pseudorandom {@code double} values,
* each with the given origin (inclusive) and bound (exclusive) * each with the given origin (inclusive) and bound (exclusive)
* @throws IllegalArgumentException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc}
* @since 1.8 * @since 1.8
*/ */
@Override @Override

View file

@ -627,7 +627,8 @@ public enum SourceVersion {
* {@code "17"}, to the corresponding source version, {@code * {@code "17"}, to the corresponding source version, {@code
* RELEASE_17}, is: * RELEASE_17}, is:
* *
* <pre>{@code SourceVersion.valueOf(Runtime.Version.parse("17"))}</pre> * {@snippet lang="java" :
* SourceVersion.valueOf(Runtime.Version.parse("17"))}
* *
* @param rv runtime version to map to a source version * @param rv runtime version to map to a source version
* @throws IllegalArgumentException if the feature of version * @throws IllegalArgumentException if the feature of version

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,7 @@ import static org.testng.Assert.*;
* @test * @test
* @run testng RandomTest * @run testng RandomTest
* @summary test methods on Random * @summary test methods on Random
* @bug 8288596
* @key randomness * @key randomness
*/ */
@Test @Test
@ -445,4 +446,50 @@ public class RandomTest {
assertSame(randomInstance, randomInstanceCopy); assertSame(randomInstance, randomInstanceCopy);
} }
private int delegationCount;
private class RandomGen implements RandomGenerator {
@Override
public boolean isDeprecated() {
delegationCount += 1;
return RandomGenerator.super.isDeprecated();
}
@Override
public float nextFloat(float bound) {
delegationCount += 1;
return RandomGenerator.super.nextFloat(bound);
}
@Override
public double nextDouble(double bound) {
delegationCount += 1;
return RandomGenerator.super.nextDouble(bound);
}
@Override
public long nextLong() {
return 0;
}
}
/*
* Test whether calls to methods inherited from RandomGenerator
* are delegated to the instance returned by from().
* This is not a complete coverage, but simulates the reproducer
* in issue JDK-8288596
*/
public void testRandomFrom() {
delegationCount = 0;
var r = Random.from(new RandomGen());
r.isDeprecated();
r.nextFloat(1_000.0f);
r.nextFloat(); // not implemented in RandomGen, does not count
r.nextDouble(1_000.0);
r.nextDouble(); // not implemented in RandomGen, does not count
assertEquals(delegationCount, 3);
}
} }