< prev index next >

src/java.base/share/classes/java/util/Locale.java

Print this page
rev 54349 : 8221701: Archive constant BaseLocales
Reviewed-by: TBD


 467  * <p>The Locale constructors have always specified that the language
 468  * and the country param be two characters in length, although in
 469  * practice they have accepted any length.  The specification has now
 470  * been relaxed to allow language codes of two to eight characters and
 471  * country (region) codes of two to three characters, and in
 472  * particular, three-letter language codes and three-digit region
 473  * codes as specified in the IANA Language Subtag Registry.  For
 474  * compatibility, the implementation still does not impose a length
 475  * constraint.
 476  *
 477  * @see Builder
 478  * @see ResourceBundle
 479  * @see java.text.Format
 480  * @see java.text.NumberFormat
 481  * @see java.text.Collator
 482  * @author Mark Davis
 483  * @since 1.1
 484  */
 485 public final class Locale implements Cloneable, Serializable {
 486 
 487     private static final  Cache LOCALECACHE = new Cache();
 488 
 489     /** Useful constant for language.
 490      */
 491     public static final Locale ENGLISH = createConstant("en", "");
 492 
 493     /** Useful constant for language.
 494      */
 495     public static final Locale FRENCH = createConstant("fr", "");
 496 
 497     /** Useful constant for language.
 498      */
 499     public static final Locale GERMAN = createConstant("de", "");
 500 
 501     /** Useful constant for language.
 502      */
 503     public static final Locale ITALIAN = createConstant("it", "");
 504 
 505     /** Useful constant for language.
 506      */
 507     public static final Locale JAPANESE = createConstant("ja", "");
 508 
 509     /** Useful constant for language.
 510      */
 511     public static final Locale KOREAN = createConstant("ko", "");
 512 
 513     /** Useful constant for language.
 514      */
 515     public static final Locale CHINESE = createConstant("zh", "");
 516 
 517     /** Useful constant for language.
 518      */
 519     public static final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
 520 
 521     /** Useful constant for language.
 522      */
 523     public static final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
 524 
 525     /** Useful constant for country.
 526      */
 527     public static final Locale FRANCE = createConstant("fr", "FR");
 528 
 529     /** Useful constant for country.
 530      */
 531     public static final Locale GERMANY = createConstant("de", "DE");
 532 
 533     /** Useful constant for country.
 534      */
 535     public static final Locale ITALY = createConstant("it", "IT");
 536 
 537     /** Useful constant for country.
 538      */
 539     public static final Locale JAPAN = createConstant("ja", "JP");
 540 
 541     /** Useful constant for country.
 542      */
 543     public static final Locale KOREA = createConstant("ko", "KR");
 544 
 545     /** Useful constant for country.
 546      */
 547     public static final Locale CHINA = SIMPLIFIED_CHINESE;
 548 
 549     /** Useful constant for country.
 550      */
 551     public static final Locale PRC = SIMPLIFIED_CHINESE;
 552 
 553     /** Useful constant for country.
 554      */
 555     public static final Locale TAIWAN = TRADITIONAL_CHINESE;
 556 
 557     /** Useful constant for country.
 558      */
 559     public static final Locale UK = createConstant("en", "GB");










































 560 
 561     /** Useful constant for country.
 562      */
 563     public static final Locale US = createConstant("en", "US");
 564 
 565     /** Useful constant for country.
 566      */
 567     public static final Locale CANADA = createConstant("en", "CA");
 568 
 569     /** Useful constant for country.
 570      */
 571     public static final Locale CANADA_FRENCH = createConstant("fr", "CA");
 572 
 573     /**
 574      * Useful constant for the root locale.  The root locale is the locale whose
 575      * language, country, and variant are empty ("") strings.  This is regarded
 576      * as the base locale of all locales, and is used as the language/country
 577      * neutral locale for the locale sensitive operations.
 578      *
 579      * @since 1.6
 580      */
 581     public static final Locale ROOT = createConstant("", "");




















 582 
 583     /**
 584      * The key for the private use extension ('x').
 585      *
 586      * @see #getExtension(char)
 587      * @see Builder#setExtension(char, String)
 588      * @since 1.7
 589      */
 590     public static final char PRIVATE_USE_EXTENSION = 'x';
 591 
 592     /**
 593      * The key for Unicode locale extension ('u').
 594      *
 595      * @see #getExtension(char)
 596      * @see Builder#setExtension(char, String)
 597      * @since 1.7
 598      */
 599     public static final char UNICODE_LOCALE_EXTENSION = 'u';
 600 
 601     /** serialization ID


 692      * <li>ISO 639 is not a stable standard; some of the language codes it defines
 693      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
 694      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
 695      * API on Locale will return only the OLD codes.
 696      * <li>For backward compatibility reasons, this constructor does not make
 697      * any syntactic checks on the input.
 698      * <li>The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
 699      * see <a href="#special_cases_constructor">Special Cases</a> for more information.
 700      * </ul>
 701      *
 702      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
 703      * up to 8 characters in length.  See the <code>Locale</code> class description about
 704      * valid language values.
 705      * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
 706      * See the <code>Locale</code> class description about valid country values.
 707      * @param variant Any arbitrary value used to indicate a variation of a <code>Locale</code>.
 708      * See the <code>Locale</code> class description for the details.
 709      * @exception NullPointerException thrown if any argument is null.
 710      */
 711     public Locale(String language, String country, String variant) {
 712         if (language== null || country == null || variant == null) {
 713             throw new NullPointerException();
 714         }
 715         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
 716         localeExtensions = getCompatibilityExtensions(language, "", country, variant);
 717     }
 718 
 719     /**
 720      * Construct a locale from language and country.
 721      * This constructor normalizes the language value to lowercase and
 722      * the country value to uppercase.
 723      * <p>
 724      * <b>Note:</b>
 725      * <ul>
 726      * <li>ISO 639 is not a stable standard; some of the language codes it defines
 727      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
 728      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
 729      * API on Locale will return only the OLD codes.
 730      * <li>For backward compatibility reasons, this constructor does not make
 731      * any syntactic checks on the input.
 732      * </ul>


 750      * <ul>
 751      * <li>ISO 639 is not a stable standard; some of the language codes it defines
 752      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
 753      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
 754      * API on Locale will return only the OLD codes.
 755      * <li>For backward compatibility reasons, this constructor does not make
 756      * any syntactic checks on the input.
 757      * </ul>
 758      *
 759      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
 760      * up to 8 characters in length.  See the <code>Locale</code> class description about
 761      * valid language values.
 762      * @exception NullPointerException thrown if argument is null.
 763      * @since 1.4
 764      */
 765     public Locale(String language) {
 766         this(language, "", "");
 767     }
 768 
 769     /**
 770      * This method must be called only for creating the Locale.*
 771      * constants due to making shortcuts.
 772      */
 773     private static Locale createConstant(String lang, String country) {
 774         BaseLocale base = BaseLocale.createInstance(lang, country);
 775         return getInstance(base, null);
 776     }
 777 
 778     /**
 779      * Returns a <code>Locale</code> constructed from the given
 780      * <code>language</code>, <code>country</code> and
 781      * <code>variant</code>. If the same <code>Locale</code> instance
 782      * is available in the cache, then that instance is
 783      * returned. Otherwise, a new <code>Locale</code> instance is
 784      * created and cached.
 785      *
 786      * @param language lowercase 2 to 8 language code.
 787      * @param country uppercase two-letter ISO-3166 code and numeric-3 UN M.49 area code.
 788      * @param variant vendor and browser specific code. See class description.
 789      * @return the <code>Locale</code> instance requested
 790      * @exception NullPointerException if any argument is null.
 791      */
 792     static Locale getInstance(String language, String country, String variant) {
 793         return getInstance(language, "", country, variant, null);
 794     }
 795 
 796     static Locale getInstance(String language, String script, String country,
 797                                       String variant, LocaleExtensions extensions) {
 798         if (language== null || script == null || country == null || variant == null) {
 799             throw new NullPointerException();
 800         }
 801 
 802         if (extensions == null) {
 803             extensions = getCompatibilityExtensions(language, script, country, variant);
 804         }
 805 
 806         BaseLocale baseloc = BaseLocale.getInstance(language, script, country, variant);
 807         return getInstance(baseloc, extensions);
 808     }
 809 
 810     static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
 811         if (extensions == null) {
 812             return LOCALECACHE.get(baseloc);




 813         } else {
 814             LocaleKey key = new LocaleKey(baseloc, extensions);
 815             return LOCALECACHE.get(key);
 816         }
 817     }
 818 
 819     private static class Cache extends LocaleObjectCache<Object, Locale> {



 820         private Cache() {
 821         }
 822 
 823         @Override
 824         protected Locale createObject(Object key) {
 825             if (key instanceof BaseLocale) {
 826                 return new Locale((BaseLocale)key, null);
 827             } else {
 828                 LocaleKey lk = (LocaleKey)key;
 829                 return new Locale(lk.base, lk.exts);
 830             }
 831         }
 832     }
 833 
 834     private static final class LocaleKey {
 835         private final BaseLocale base;
 836         private final LocaleExtensions exts;
 837         private final int hash;
 838 
 839         private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {


 960                     .orElse(null));
 961     }
 962 
 963     private static Locale initDefault(Locale.Category category) {
 964         Properties props = GetPropertyAction.privilegedGetProperties();
 965 
 966         return getInstance(
 967             props.getProperty(category.languageKey,
 968                     defaultLocale.getLanguage()),
 969             props.getProperty(category.scriptKey,
 970                     defaultLocale.getScript()),
 971             props.getProperty(category.countryKey,
 972                     defaultLocale.getCountry()),
 973             props.getProperty(category.variantKey,
 974                     defaultLocale.getVariant()),
 975             getDefaultExtensions(props.getProperty(category.extensionsKey, ""))
 976                 .orElse(defaultLocale.getLocaleExtensions()));
 977     }
 978 
 979     private static Optional<LocaleExtensions> getDefaultExtensions(String extensionsProp) {
 980         LocaleExtensions exts = null;


 981 

 982         try {
 983             exts = new InternalLocaleBuilder()
 984                 .setExtensions(extensionsProp)
 985                 .getLocaleExtensions();
 986         } catch (LocaleSyntaxException e) {
 987             // just ignore this incorrect property
 988         }
 989 
 990         return Optional.ofNullable(exts);
 991     }
 992 
 993     /**
 994      * Sets the default locale for this instance of the Java Virtual Machine.
 995      * This does not affect the host locale.
 996      * <p>
 997      * If there is a security manager, its <code>checkPermission</code>
 998      * method is called with a <code>PropertyPermission("user.language", "write")</code>
 999      * permission before the default locale is changed.
1000      * <p>
1001      * The Java Virtual Machine sets the default locale during startup


2291         fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
2292         fields.put("hashcode", -1); // place holder just for backward support
2293         out.writeFields();
2294     }
2295 
2296     /**
2297      * Deserializes this <code>Locale</code>.
2298      * @param in the <code>ObjectInputStream</code> to read
2299      * @throws IOException
2300      * @throws ClassNotFoundException
2301      * @throws IllformedLocaleException
2302      * @since 1.7
2303      */
2304     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
2305         ObjectInputStream.GetField fields = in.readFields();
2306         String language = (String)fields.get("language", "");
2307         String script = (String)fields.get("script", "");
2308         String country = (String)fields.get("country", "");
2309         String variant = (String)fields.get("variant", "");
2310         String extStr = (String)fields.get("extensions", "");

2311         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
2312         if (!extStr.isEmpty()) {
2313             try {
2314                 InternalLocaleBuilder bldr = new InternalLocaleBuilder();
2315                 bldr.setExtensions(extStr);
2316                 localeExtensions = bldr.getLocaleExtensions();
2317             } catch (LocaleSyntaxException e) {
2318                 throw new IllformedLocaleException(e.getMessage());
2319             }
2320         } else {
2321             localeExtensions = null;
2322         }
2323     }
2324 
2325     /**
2326      * Returns a cached <code>Locale</code> instance equivalent to
2327      * the deserialized <code>Locale</code>. When serialized
2328      * language, country and variant fields read from the object data stream
2329      * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
2330      * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>




 467  * <p>The Locale constructors have always specified that the language
 468  * and the country param be two characters in length, although in
 469  * practice they have accepted any length.  The specification has now
 470  * been relaxed to allow language codes of two to eight characters and
 471  * country (region) codes of two to three characters, and in
 472  * particular, three-letter language codes and three-digit region
 473  * codes as specified in the IANA Language Subtag Registry.  For
 474  * compatibility, the implementation still does not impose a length
 475  * constraint.
 476  *
 477  * @see Builder
 478  * @see ResourceBundle
 479  * @see java.text.Format
 480  * @see java.text.NumberFormat
 481  * @see java.text.Collator
 482  * @author Mark Davis
 483  * @since 1.1
 484  */
 485 public final class Locale implements Cloneable, Serializable {
 486 


 487     /** Useful constant for language.
 488      */
 489     public static final Locale ENGLISH;
 490 
 491     /** Useful constant for language.
 492      */
 493     public static final Locale FRENCH;
 494 
 495     /** Useful constant for language.
 496      */
 497     public static final Locale GERMAN;
 498 
 499     /** Useful constant for language.
 500      */
 501     public static final Locale ITALIAN;
 502 
 503     /** Useful constant for language.
 504      */
 505     public static final Locale JAPANESE;
 506 
 507     /** Useful constant for language.
 508      */
 509     public static final Locale KOREAN;
 510 
 511     /** Useful constant for language.
 512      */
 513     public static final Locale CHINESE;
 514 
 515     /** Useful constant for language.
 516      */
 517     public static final Locale SIMPLIFIED_CHINESE;
 518 
 519     /** Useful constant for language.
 520      */
 521     public static final Locale TRADITIONAL_CHINESE;
 522 
 523     /** Useful constant for country.
 524      */
 525     public static final Locale FRANCE;
 526 
 527     /** Useful constant for country.
 528      */
 529     public static final Locale GERMANY;
 530 
 531     /** Useful constant for country.
 532      */
 533     public static final Locale ITALY;
 534 
 535     /** Useful constant for country.
 536      */
 537     public static final Locale JAPAN;
 538 
 539     /** Useful constant for country.
 540      */
 541     public static final Locale KOREA;
 542 
 543     /** Useful constant for country.
 544      */
 545     public static final Locale UK;
 546 
 547     /** Useful constant for country.
 548      */
 549     public static final Locale US;
 550 
 551     /** Useful constant for country.
 552      */
 553     public static final Locale CANADA;
 554 
 555     /** Useful constant for country.
 556      */
 557     public static final Locale CANADA_FRENCH;
 558 
 559     /**
 560      * Useful constant for the root locale.  The root locale is the locale whose
 561      * language, country, and variant are empty ("") strings.  This is regarded
 562      * as the base locale of all locales, and is used as the language/country
 563      * neutral locale for the locale sensitive operations.
 564      *
 565      * @since 1.6
 566      */
 567     public static final Locale ROOT;
 568 
 569     private static final Map<BaseLocale, Locale> CONSTANT_LOCALES = new HashMap<>();
 570 
 571     static {
 572         var baseLocales = BaseLocale.constantBaseLocales;
 573         boolean fromArchive = baseLocales != null;
 574         if (!fromArchive) {
 575             baseLocales = new HashMap<>();
 576         }
 577         ENGLISH = constant("en", "", baseLocales, fromArchive);
 578         FRENCH = constant("fr", "", baseLocales, fromArchive);
 579         GERMAN = constant("de", "", baseLocales, fromArchive);
 580         ITALIAN = constant("it", "", baseLocales, fromArchive);
 581         JAPANESE = constant("ja", "", baseLocales, fromArchive);
 582         KOREAN = constant("ko", "", baseLocales, fromArchive);
 583         CHINESE = constant("zh", "", baseLocales, fromArchive);
 584         SIMPLIFIED_CHINESE = constant("zh", "CN", baseLocales, fromArchive);
 585         TRADITIONAL_CHINESE = constant("zh", "TW", baseLocales, fromArchive);
 586         FRANCE = constant("fr", "FR", baseLocales, fromArchive);
 587         GERMANY = constant("de", "DE", baseLocales, fromArchive);
 588         ITALY = constant("it", "IT", baseLocales, fromArchive);
 589         JAPAN = constant("ja", "JP", baseLocales, fromArchive);
 590         KOREA = constant("ko", "KR", baseLocales, fromArchive);
 591         UK = constant("en", "GB", baseLocales, fromArchive);
 592         US = constant("en", "US", baseLocales, fromArchive);
 593         CANADA = constant("en", "CA", baseLocales, fromArchive);
 594         CANADA_FRENCH = constant("fr", "CA", baseLocales, fromArchive);
 595         ROOT = constant("", "", baseLocales, fromArchive);
 596         if (!fromArchive) {
 597             BaseLocale.constantBaseLocales = Map.copyOf(baseLocales);
 598         }
 599     }
 600 
 601     /** Useful constant for country.
 602      */
 603     public static final Locale CHINA = SIMPLIFIED_CHINESE;
 604 
 605     /** Useful constant for country.
 606      */
 607     public static final Locale PRC = SIMPLIFIED_CHINESE;
 608 
 609     /** Useful constant for country.
 610      */
 611     public static final Locale TAIWAN = TRADITIONAL_CHINESE;
 612 
 613     /**
 614      * This method must be called only for creating the Locale.*
 615      * constants due to making shortcuts.




 616      */
 617     private static Locale constant(String lang,
 618                                    String country,
 619                                    Map<String, Map<String, BaseLocale>> baseLocaleMap,
 620                                    boolean fromArchive) {
 621         BaseLocale base;
 622         if (fromArchive) {
 623             var countryMap = baseLocaleMap.get(lang);
 624             base = countryMap.get(country);
 625         } else {
 626             base = BaseLocale.createInstance(lang, country);
 627             var countryMap = baseLocaleMap.get(lang);
 628             if (countryMap == null) {
 629                 countryMap = new HashMap<>();
 630                 baseLocaleMap.put(lang, countryMap);
 631             }
 632             countryMap.put(country, base);
 633         }
 634         Locale locale = new Locale(base, null);
 635         CONSTANT_LOCALES.put(base, locale);
 636         return locale;
 637     }
 638 
 639     /**
 640      * The key for the private use extension ('x').
 641      *
 642      * @see #getExtension(char)
 643      * @see Builder#setExtension(char, String)
 644      * @since 1.7
 645      */
 646     public static final char PRIVATE_USE_EXTENSION = 'x';
 647 
 648     /**
 649      * The key for Unicode locale extension ('u').
 650      *
 651      * @see #getExtension(char)
 652      * @see Builder#setExtension(char, String)
 653      * @since 1.7
 654      */
 655     public static final char UNICODE_LOCALE_EXTENSION = 'u';
 656 
 657     /** serialization ID


 748      * <li>ISO 639 is not a stable standard; some of the language codes it defines
 749      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
 750      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
 751      * API on Locale will return only the OLD codes.
 752      * <li>For backward compatibility reasons, this constructor does not make
 753      * any syntactic checks on the input.
 754      * <li>The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
 755      * see <a href="#special_cases_constructor">Special Cases</a> for more information.
 756      * </ul>
 757      *
 758      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
 759      * up to 8 characters in length.  See the <code>Locale</code> class description about
 760      * valid language values.
 761      * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
 762      * See the <code>Locale</code> class description about valid country values.
 763      * @param variant Any arbitrary value used to indicate a variation of a <code>Locale</code>.
 764      * See the <code>Locale</code> class description for the details.
 765      * @exception NullPointerException thrown if any argument is null.
 766      */
 767     public Locale(String language, String country, String variant) {
 768         if (language == null || country == null || variant == null) {
 769             throw new NullPointerException();
 770         }
 771         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
 772         localeExtensions = getCompatibilityExtensions(language, "", country, variant);
 773     }
 774 
 775     /**
 776      * Construct a locale from language and country.
 777      * This constructor normalizes the language value to lowercase and
 778      * the country value to uppercase.
 779      * <p>
 780      * <b>Note:</b>
 781      * <ul>
 782      * <li>ISO 639 is not a stable standard; some of the language codes it defines
 783      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
 784      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
 785      * API on Locale will return only the OLD codes.
 786      * <li>For backward compatibility reasons, this constructor does not make
 787      * any syntactic checks on the input.
 788      * </ul>


 806      * <ul>
 807      * <li>ISO 639 is not a stable standard; some of the language codes it defines
 808      * (specifically "iw", "ji", and "in") have changed.  This constructor accepts both the
 809      * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
 810      * API on Locale will return only the OLD codes.
 811      * <li>For backward compatibility reasons, this constructor does not make
 812      * any syntactic checks on the input.
 813      * </ul>
 814      *
 815      * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
 816      * up to 8 characters in length.  See the <code>Locale</code> class description about
 817      * valid language values.
 818      * @exception NullPointerException thrown if argument is null.
 819      * @since 1.4
 820      */
 821     public Locale(String language) {
 822         this(language, "", "");
 823     }
 824 
 825     /**









 826      * Returns a <code>Locale</code> constructed from the given
 827      * <code>language</code>, <code>country</code> and
 828      * <code>variant</code>. If the same <code>Locale</code> instance
 829      * is available in the cache, then that instance is
 830      * returned. Otherwise, a new <code>Locale</code> instance is
 831      * created and cached.
 832      *
 833      * @param language lowercase 2 to 8 language code.
 834      * @param country uppercase two-letter ISO-3166 code and numeric-3 UN M.49 area code.
 835      * @param variant vendor and browser specific code. See class description.
 836      * @return the <code>Locale</code> instance requested
 837      * @exception NullPointerException if any argument is null.
 838      */
 839     static Locale getInstance(String language, String country, String variant) {
 840         return getInstance(language, "", country, variant, null);
 841     }
 842 
 843     static Locale getInstance(String language, String script, String country,
 844                                       String variant, LocaleExtensions extensions) {
 845         if (language== null || script == null || country == null || variant == null) {
 846             throw new NullPointerException();
 847         }
 848 
 849         if (extensions == null) {
 850             extensions = getCompatibilityExtensions(language, script, country, variant);
 851         }
 852 
 853         BaseLocale baseloc = BaseLocale.getInstance(language, script, country, variant);
 854         return getInstance(baseloc, extensions);
 855     }
 856 
 857     static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
 858         if (extensions == null) {
 859             Locale locale = CONSTANT_LOCALES.get(baseloc);
 860             if (locale != null) {
 861                 return locale;
 862             }
 863             return Cache.LOCALECACHE.get(baseloc);
 864         } else {
 865             LocaleKey key = new LocaleKey(baseloc, extensions);
 866             return Cache.LOCALECACHE.get(key);
 867         }
 868     }
 869 
 870     private static class Cache extends LocaleObjectCache<Object, Locale> {
 871 
 872         private static final Cache LOCALECACHE = new Cache();
 873 
 874         private Cache() {
 875         }
 876 
 877         @Override
 878         protected Locale createObject(Object key) {
 879             if (key instanceof BaseLocale) {
 880                 return new Locale((BaseLocale)key, null);
 881             } else {
 882                 LocaleKey lk = (LocaleKey)key;
 883                 return new Locale(lk.base, lk.exts);
 884             }
 885         }
 886     }
 887 
 888     private static final class LocaleKey {
 889         private final BaseLocale base;
 890         private final LocaleExtensions exts;
 891         private final int hash;
 892 
 893         private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {


1014                     .orElse(null));
1015     }
1016 
1017     private static Locale initDefault(Locale.Category category) {
1018         Properties props = GetPropertyAction.privilegedGetProperties();
1019 
1020         return getInstance(
1021             props.getProperty(category.languageKey,
1022                     defaultLocale.getLanguage()),
1023             props.getProperty(category.scriptKey,
1024                     defaultLocale.getScript()),
1025             props.getProperty(category.countryKey,
1026                     defaultLocale.getCountry()),
1027             props.getProperty(category.variantKey,
1028                     defaultLocale.getVariant()),
1029             getDefaultExtensions(props.getProperty(category.extensionsKey, ""))
1030                 .orElse(defaultLocale.getLocaleExtensions()));
1031     }
1032 
1033     private static Optional<LocaleExtensions> getDefaultExtensions(String extensionsProp) {
1034         if (LocaleUtils.isEmpty(extensionsProp)) {
1035             return Optional.empty();
1036         }
1037 
1038         LocaleExtensions exts = null;
1039         try {
1040             exts = new InternalLocaleBuilder()
1041                 .setExtensions(extensionsProp)
1042                 .getLocaleExtensions();
1043         } catch (LocaleSyntaxException e) {
1044             // just ignore this incorrect property
1045         }
1046 
1047         return Optional.ofNullable(exts);
1048     }
1049 
1050     /**
1051      * Sets the default locale for this instance of the Java Virtual Machine.
1052      * This does not affect the host locale.
1053      * <p>
1054      * If there is a security manager, its <code>checkPermission</code>
1055      * method is called with a <code>PropertyPermission("user.language", "write")</code>
1056      * permission before the default locale is changed.
1057      * <p>
1058      * The Java Virtual Machine sets the default locale during startup


2348         fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
2349         fields.put("hashcode", -1); // place holder just for backward support
2350         out.writeFields();
2351     }
2352 
2353     /**
2354      * Deserializes this <code>Locale</code>.
2355      * @param in the <code>ObjectInputStream</code> to read
2356      * @throws IOException
2357      * @throws ClassNotFoundException
2358      * @throws IllformedLocaleException
2359      * @since 1.7
2360      */
2361     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
2362         ObjectInputStream.GetField fields = in.readFields();
2363         String language = (String)fields.get("language", "");
2364         String script = (String)fields.get("script", "");
2365         String country = (String)fields.get("country", "");
2366         String variant = (String)fields.get("variant", "");
2367         String extStr = (String)fields.get("extensions", "");
2368 
2369         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
2370         if (!extStr.isEmpty()) {
2371             try {
2372                 InternalLocaleBuilder bldr = new InternalLocaleBuilder();
2373                 bldr.setExtensions(extStr);
2374                 localeExtensions = bldr.getLocaleExtensions();
2375             } catch (LocaleSyntaxException e) {
2376                 throw new IllformedLocaleException(e.getMessage());
2377             }
2378         } else {
2379             localeExtensions = null;
2380         }
2381     }
2382 
2383     /**
2384      * Returns a cached <code>Locale</code> instance equivalent to
2385      * the deserialized <code>Locale</code>. When serialized
2386      * language, country and variant fields read from the object data stream
2387      * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
2388      * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>


< prev index next >