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

Deprecate Locale class constructors

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Approved
    • Fix Version/s: 19
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      source
    • Compatibility Risk:
      low
    • Compatibility Risk Description:
      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)
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      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, countryand/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.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              naoto Naoto Sato
              Reporter:
              naoto Naoto Sato
              Reviewed By:
              Roger Riggs, Stuart Marks
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: