-
CSR
-
Resolution: Approved
-
P4
-
None
-
source
-
low
-
Although there is no code changes, rebuilding existing apps may throw the deprecation warning, which could end up a compilation error (depending on the compiler settings)
-
Java API
-
SE
Summary
Deprecate the use of constructors in java.util.Locale
class
Problem
Since JDK 7, Locale
class provides the factory method forLanguageTag()
and the builder Locale.Builder
. There's no need to use those constructors anymore, in fact, there are a couple of reasons to discourage the usage:
- Constructors do not validate the arguments that produce
ill-formed
locale objects. - The factory method and the builder produce a singleton instance, while constructors create different objects for the same arguments. Using singletons is more performant in
equals()
and consuming less resources.
Solution
Mark the three constructors, Locale(String)
, Locale(String, String)
, and Locale(String, String, String)
as deprecated, but not terminally. However, we cannot make them forRemoval=true
because serialized Locale objects with ill-formed
arguments, such as Locale("a", "A", "a")
, cannot be deserialized without constructors. Also, add 3 new factory methods to take legacy (non bcp47 conforming) language
, country
and/or variant
fields. Each new factory method makes 1-1 corresponding to the existing (now deprecated) constructor so that users can easily migrate their code by simply using regex s/new Locale(/Locale.of(/
.
Specification
In the java.util.Locale
class, make the following documentation changes:
Throughout the javadoc in Locale class, change the verb used to instantiate a Locale object from "create" to "obtain."
In the class description, modify the "Creating a Locale" section as follows so that it can be referred from the deprecated constructors:
- * <h3>Creating a Locale</h3>
+ * <h3><a id="ObtainingLocale">Obtaining a Locale</a></h3>
*
- * <p>There are several different ways to create a {@code Locale}
+ * <p>There are several ways to obtain a {@code Locale}
* object.
*
Change the following section regarding factory methods:
* <p>The method {@link #forLanguageTag} obtains a {@code Locale}
- * object for a well-formed BCP 47 language tag.
+ * object for a well-formed BCP 47 language tag. The method
+ * {@link #of(String, String, String)} and its overloads obtain a
+ * {@code Locale} object from given ({@code language}, {@code country},
+ * and/or {@code variant} defined above.
Change the following section about Locale Constants for better readability:
* <p>The {@code Locale} class provides a number of convenient constants
* that you can use to obtain {@code Locale} objects for commonly used
- * locales. For example, the following obtains a {@code Locale} object
- * for the United States:
- * <blockquote>
- * <pre>
- * Locale.US
- * </pre>
- * </blockquote>
+ * locales. For example, {@code Locale.US} is the {@code Locale} object
+ * for the United States.
Remove the following section.
*
- * <h4>Constructors</h4>
- *
- * <p>The {@code Locale} class provides three constructors:
- * <blockquote>
- * <pre>
- * {@link #Locale(String language)}
- * {@link #Locale(String language, String country)}
- * {@link #Locale(String language, String country, String variant)}
- * </pre>
- * </blockquote>
- * These constructors allow you to create a {@code Locale} object
- * with language, country and variant, but you cannot specify
- * script or extensions.
- *
Although we remove the above explanation for creating a locale with constructors, other references to constructors remain intact so that users can still find them useful for migration to other means.
Add the following javadoc tag to each of those three constructors' documentation.
+ * @deprecated Locale constructors have been deprecated. See <a href ="#ObtainingLocale">
+ * Obtaining a Locale</a> for other options.
Add the following annotation to each of those three constructors' declarations.
+ @Deprecated(since="19")
Add 3 new factory methods as follows:
+ /**
+ * Obtains a locale from language, country and variant.
+ * This method normalizes the language value to lowercase and
+ * the country value to uppercase.
+ * @implNote
+ * <ul>
+ * <li>This method does not make any syntactic checks on the input.
+ * Use {@link Locale.Builder} for full syntactic checks with BCP47.
+ * <li>The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
+ * see <a href="#special_cases_constructor">Special Cases</a> for more information.
+ * <li>Obsolete ISO 639 codes ("iw", "ji", and "in") are mapped to
+ * their current forms. See <a href="#legacy_language_codes">Legacy language
+ * codes</a> for more information.
+ * </ul>
+ *
+ * @param language A language code. See the {@code Locale} class description of
+ * <a href="#def_language">language</a> values.
+ * @param country A country code. See the {@code Locale} class description of
+ * <a href="#def_region">country</a> values.
+ * @param variant Any arbitrary value used to indicate a variation of a {@code Locale}.
+ * See the {@code Locale} class description of <a href="#def_variant">variant</a> values.
+ * @throws NullPointerException thrown if any argument is null.
+ * @return A {@code Locale} object
+ * @since 19
+ */
+ public static Locale of(String language, String country, String variant)
+
+ /**
+ * Obtains a locale from language and country.
+ * This method normalizes the language value to lowercase and
+ * the country value to uppercase.
+ * @implNote
+ * <ul>
+ * <li>This method does not make any syntactic checks on the input.
+ * Use {@link Locale.Builder} for full syntactic checks with BCP47.
+ * <li>Obsolete ISO 639 codes ("iw", "ji", and "in") are mapped to
+ * their current forms. See <a href="#legacy_language_codes">Legacy language
+ * codes</a> for more information.
+ * </ul>
+ *
+ * @param language A language code. See the {@code Locale} class description of
+ * <a href="#def_language">language</a> values.
+ * @param country A country code. See the {@code Locale} class description of
+ * <a href="#def_region">country</a> values.
+ * @throws NullPointerException thrown if either argument is null.
+ * @return A {@code Locale} object
+ * @since 19
+ */
+ public static Locale of(String language, String country)
+
+ /**
+ * Obtains a locale from a language code.
+ * This method normalizes the language value to lowercase.
+ * @implNote
+ * <ul>
+ * <li>This method does not make any syntactic checks on the input.
+ * Use {@link Locale.Builder} for full syntactic checks with BCP47.
+ * <li>Obsolete ISO 639 codes ("iw", "ji", and "in") are mapped to
+ * their current forms. See <a href="#legacy_language_codes">Legacy language
+ * codes</a> for more information.
+ * </ul>
+ *
+ * @param language A language code. See the {@code Locale} class description of
+ * <a href="#def_language">language</a> values.
+ * @throws NullPointerException thrown if argument is null.
+ * @return A {@code Locale} object
+ * @since 19
+ */
+ public static Locale of(String language)
Apart from this deprecation, the following change is suggested in the class documentation:
* <h3>Compatibility</h3>
*
- * <p>In order to maintain compatibility with existing usage, Locale's
+ * <p>In order to maintain compatibility, Locale's
* constructors retain their behavior prior to the Java Runtime
The wording "existing usage" was introduced when Locale was enhanced with bcp47 in JDK7. It is confusing as of now, so simply removing it is desired.
- csr of
-
JDK-8282819 Deprecate Locale class constructors
- Resolved