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 ENGLISH = createConstant(BaseLocale.ENGLISH);
573 FRENCH = createConstant(BaseLocale.FRENCH);
574 GERMAN = createConstant(BaseLocale.GERMAN);
575 ITALIAN = createConstant(BaseLocale.ITALIAN);
576 JAPANESE = createConstant(BaseLocale.JAPANESE);
577 KOREAN = createConstant(BaseLocale.KOREAN);
578 CHINESE = createConstant(BaseLocale.CHINESE);
579 SIMPLIFIED_CHINESE = createConstant(BaseLocale.SIMPLIFIED_CHINESE);
580 TRADITIONAL_CHINESE = createConstant(BaseLocale.TRADITIONAL_CHINESE);
581 FRANCE = createConstant(BaseLocale.FRANCE);
582 GERMANY = createConstant(BaseLocale.GERMANY);
583 ITALY = createConstant(BaseLocale.ITALY);
584 JAPAN = createConstant(BaseLocale.JAPAN);
585 KOREA = createConstant(BaseLocale.KOREA);
586 UK = createConstant(BaseLocale.UK);
587 US = createConstant(BaseLocale.US);
588 CANADA = createConstant(BaseLocale.CANADA);
589 CANADA_FRENCH = createConstant(BaseLocale.CANADA_FRENCH);
590 ROOT = createConstant(BaseLocale.ROOT);
591 }
592
593 /** Useful constant for country.
594 */
595 public static final Locale CHINA = SIMPLIFIED_CHINESE;
596
597 /** Useful constant for country.
598 */
599 public static final Locale PRC = SIMPLIFIED_CHINESE;
600
601 /** Useful constant for country.
602 */
603 public static final Locale TAIWAN = TRADITIONAL_CHINESE;
604
605 /**
606 * This method must be called only for creating the Locale.*
607 * constants due to making shortcuts.
608 */
609 private static Locale createConstant(byte baseType) {
610 BaseLocale base = BaseLocale.constantBaseLocales[baseType];
611 Locale locale = new Locale(base, null);
612 CONSTANT_LOCALES.put(base, locale);
613 return locale;
614 }
615
616 /**
617 * The key for the private use extension ('x').
618 *
619 * @see #getExtension(char)
620 * @see Builder#setExtension(char, String)
621 * @since 1.7
622 */
623 public static final char PRIVATE_USE_EXTENSION = 'x';
624
625 /**
626 * The key for Unicode locale extension ('u').
627 *
628 * @see #getExtension(char)
629 * @see Builder#setExtension(char, String)
630 * @since 1.7
631 */
632 public static final char UNICODE_LOCALE_EXTENSION = 'u';
633
634 /** serialization ID
725 * <li>ISO 639 is not a stable standard; some of the language codes it defines
726 * (specifically "iw", "ji", and "in") have changed. This constructor accepts both the
727 * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
728 * API on Locale will return only the OLD codes.
729 * <li>For backward compatibility reasons, this constructor does not make
730 * any syntactic checks on the input.
731 * <li>The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
732 * see <a href="#special_cases_constructor">Special Cases</a> for more information.
733 * </ul>
734 *
735 * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
736 * up to 8 characters in length. See the <code>Locale</code> class description about
737 * valid language values.
738 * @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
739 * See the <code>Locale</code> class description about valid country values.
740 * @param variant Any arbitrary value used to indicate a variation of a <code>Locale</code>.
741 * See the <code>Locale</code> class description for the details.
742 * @exception NullPointerException thrown if any argument is null.
743 */
744 public Locale(String language, String country, String variant) {
745 if (language == null || country == null || variant == null) {
746 throw new NullPointerException();
747 }
748 baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
749 localeExtensions = getCompatibilityExtensions(language, "", country, variant);
750 }
751
752 /**
753 * Construct a locale from language and country.
754 * This constructor normalizes the language value to lowercase and
755 * the country value to uppercase.
756 * <p>
757 * <b>Note:</b>
758 * <ul>
759 * <li>ISO 639 is not a stable standard; some of the language codes it defines
760 * (specifically "iw", "ji", and "in") have changed. This constructor accepts both the
761 * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
762 * API on Locale will return only the OLD codes.
763 * <li>For backward compatibility reasons, this constructor does not make
764 * any syntactic checks on the input.
765 * </ul>
783 * <ul>
784 * <li>ISO 639 is not a stable standard; some of the language codes it defines
785 * (specifically "iw", "ji", and "in") have changed. This constructor accepts both the
786 * old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
787 * API on Locale will return only the OLD codes.
788 * <li>For backward compatibility reasons, this constructor does not make
789 * any syntactic checks on the input.
790 * </ul>
791 *
792 * @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
793 * up to 8 characters in length. See the <code>Locale</code> class description about
794 * valid language values.
795 * @exception NullPointerException thrown if argument is null.
796 * @since 1.4
797 */
798 public Locale(String language) {
799 this(language, "", "");
800 }
801
802 /**
803 * Returns a <code>Locale</code> constructed from the given
804 * <code>language</code>, <code>country</code> and
805 * <code>variant</code>. If the same <code>Locale</code> instance
806 * is available in the cache, then that instance is
807 * returned. Otherwise, a new <code>Locale</code> instance is
808 * created and cached.
809 *
810 * @param language lowercase 2 to 8 language code.
811 * @param country uppercase two-letter ISO-3166 code and numeric-3 UN M.49 area code.
812 * @param variant vendor and browser specific code. See class description.
813 * @return the <code>Locale</code> instance requested
814 * @exception NullPointerException if any argument is null.
815 */
816 static Locale getInstance(String language, String country, String variant) {
817 return getInstance(language, "", country, variant, null);
818 }
819
820 static Locale getInstance(String language, String script, String country,
821 String variant, LocaleExtensions extensions) {
822 if (language== null || script == null || country == null || variant == null) {
823 throw new NullPointerException();
824 }
825
826 if (extensions == null) {
827 extensions = getCompatibilityExtensions(language, script, country, variant);
828 }
829
830 BaseLocale baseloc = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
831 return getInstance(baseloc, extensions);
832 }
833
834 static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) {
835 if (extensions == null) {
836 Locale locale = CONSTANT_LOCALES.get(baseloc);
837 if (locale != null) {
838 return locale;
839 }
840 return Cache.LOCALECACHE.get(baseloc);
841 } else {
842 LocaleKey key = new LocaleKey(baseloc, extensions);
843 return Cache.LOCALECACHE.get(key);
844 }
845 }
846
847 private static class Cache extends LocaleObjectCache<Object, Locale> {
848
849 private static final Cache LOCALECACHE = new Cache();
850
851 private Cache() {
852 }
853
854 @Override
855 protected Locale createObject(Object key) {
856 if (key instanceof BaseLocale) {
857 return new Locale((BaseLocale)key, null);
858 } else {
859 LocaleKey lk = (LocaleKey)key;
860 return new Locale(lk.base, lk.exts);
861 }
862 }
863 }
864
865 private static final class LocaleKey {
866 private final BaseLocale base;
867 private final LocaleExtensions exts;
868 private final int hash;
869
870 private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {
991 .orElse(null));
992 }
993
994 private static Locale initDefault(Locale.Category category) {
995 Properties props = GetPropertyAction.privilegedGetProperties();
996
997 return getInstance(
998 props.getProperty(category.languageKey,
999 defaultLocale.getLanguage()),
1000 props.getProperty(category.scriptKey,
1001 defaultLocale.getScript()),
1002 props.getProperty(category.countryKey,
1003 defaultLocale.getCountry()),
1004 props.getProperty(category.variantKey,
1005 defaultLocale.getVariant()),
1006 getDefaultExtensions(props.getProperty(category.extensionsKey, ""))
1007 .orElse(defaultLocale.getLocaleExtensions()));
1008 }
1009
1010 private static Optional<LocaleExtensions> getDefaultExtensions(String extensionsProp) {
1011 if (LocaleUtils.isEmpty(extensionsProp)) {
1012 return Optional.empty();
1013 }
1014
1015 LocaleExtensions exts = null;
1016 try {
1017 exts = new InternalLocaleBuilder()
1018 .setExtensions(extensionsProp)
1019 .getLocaleExtensions();
1020 } catch (LocaleSyntaxException e) {
1021 // just ignore this incorrect property
1022 }
1023
1024 return Optional.ofNullable(exts);
1025 }
1026
1027 /**
1028 * Sets the default locale for this instance of the Java Virtual Machine.
1029 * This does not affect the host locale.
1030 * <p>
1031 * If there is a security manager, its <code>checkPermission</code>
1032 * method is called with a <code>PropertyPermission("user.language", "write")</code>
1033 * permission before the default locale is changed.
1034 * <p>
1035 * The Java Virtual Machine sets the default locale during startup
2325 fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
2326 fields.put("hashcode", -1); // place holder just for backward support
2327 out.writeFields();
2328 }
2329
2330 /**
2331 * Deserializes this <code>Locale</code>.
2332 * @param in the <code>ObjectInputStream</code> to read
2333 * @throws IOException
2334 * @throws ClassNotFoundException
2335 * @throws IllformedLocaleException
2336 * @since 1.7
2337 */
2338 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
2339 ObjectInputStream.GetField fields = in.readFields();
2340 String language = (String)fields.get("language", "");
2341 String script = (String)fields.get("script", "");
2342 String country = (String)fields.get("country", "");
2343 String variant = (String)fields.get("variant", "");
2344 String extStr = (String)fields.get("extensions", "");
2345
2346 baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
2347 if (!extStr.isEmpty()) {
2348 try {
2349 InternalLocaleBuilder bldr = new InternalLocaleBuilder();
2350 bldr.setExtensions(extStr);
2351 localeExtensions = bldr.getLocaleExtensions();
2352 } catch (LocaleSyntaxException e) {
2353 throw new IllformedLocaleException(e.getMessage());
2354 }
2355 } else {
2356 localeExtensions = null;
2357 }
2358 }
2359
2360 /**
2361 * Returns a cached <code>Locale</code> instance equivalent to
2362 * the deserialized <code>Locale</code>. When serialized
2363 * language, country and variant fields read from the object data stream
2364 * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
2365 * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>
|