• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4  *******************************************************************************
5  * Copyright (C) 2004-2016, Google Inc, International Business Machines
6  * Corporation and others. All Rights Reserved.
7  *******************************************************************************
8  */
9 package com.ibm.icu.util;
10 
11 import java.io.Externalizable;
12 import java.io.IOException;
13 import java.io.ObjectInput;
14 import java.io.ObjectOutput;
15 import java.io.ObjectStreamException;
16 import java.io.Serializable;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 
25 import com.ibm.icu.impl.CollectionSet;
26 import com.ibm.icu.impl.ICUData;
27 import com.ibm.icu.impl.ICUResourceBundle;
28 import com.ibm.icu.impl.UResource;
29 import com.ibm.icu.impl.units.MeasureUnitImpl;
30 import com.ibm.icu.impl.units.SingleUnitImpl;
31 import com.ibm.icu.text.UnicodeSet;
32 
33 
34 /**
35  * A unit such as length, mass, volume, currency, etc.  A unit is
36  * coupled with a numeric amount to produce a Measure. MeasureUnit objects are immutable.
37  * All subclasses must guarantee that. (However, subclassing is discouraged.)
38  *
39  * @see com.ibm.icu.util.Measure
40  * @author Alan Liu
41  * @stable ICU 3.0
42  */
43 public class MeasureUnit implements Serializable {
44     private static final long serialVersionUID = -1839973855554750484L;
45 
46     // Cache of MeasureUnits.
47     // All access to the cache or cacheIsPopulated flag must be synchronized on class MeasureUnit,
48     // i.e. from synchronized static methods. Beware of non-static methods.
49     private static final Map<String, Map<String,MeasureUnit>> cache
50         = new HashMap<>();
51     private static boolean cacheIsPopulated = false;
52 
53     /**
54      * If type set to null, measureUnitImpl is in use instead of type and subType.
55      * @internal
56      * @deprecated This API is ICU internal only.
57      */
58     @Deprecated
59     protected final String type;
60 
61     /**
62      * If subType set to null, measureUnitImpl is in use instead of type and subType.
63      * @internal
64      * @deprecated This API is ICU internal only.
65      */
66     @Deprecated
67     protected final String subType;
68 
69     /**
70      * Used by new draft APIs in ICU 68.
71      *
72      * @internal
73      */
74     private MeasureUnitImpl measureUnitImpl;
75 
76     /**
77      * Enumeration for unit complexity. There are three levels:
78      * <ul>
79      * <li>SINGLE: A single unit, optionally with a power and/or SI or binary prefix.
80      * Examples: hectare, square-kilometer, kilojoule, per-second, mebibyte.</li>
81      * <li>COMPOUND: A unit composed of the product of multiple single units. Examples:
82      * meter-per-second, kilowatt-hour, kilogram-meter-per-square-second.</li>
83      * <li>MIXED: A unit composed of the sum of multiple single units. Examples: foot-and-inch,
84      * hour-and-minute-and-second, degree-and-arcminute-and-arcsecond.</li>
85      * </ul>
86      * The complexity determines which operations are available. For example, you cannot set the power
87      * or prefix of a compound unit.
88      *
89      * @stable ICU 68
90      */
91     public enum Complexity {
92         /**
93          * A single unit, like kilojoule.
94          *
95          * @stable ICU 68
96          */
97         SINGLE,
98 
99         /**
100          * A compound unit, like meter-per-second.
101          *
102          * @stable ICU 68
103          */
104         COMPOUND,
105 
106         /**
107          * A mixed unit, like hour-and-minute.
108          *
109          * @stable ICU 68
110          */
111         MIXED
112     }
113 
114     /**
115      * Enumeration for SI and binary prefixes, e.g. "kilo-", "nano-", "mebi-".
116      *
117      * @stable ICU 69
118      */
119     public enum MeasurePrefix {
120 
121         /**
122          * SI prefix: yotta, 10^24.
123          *
124          * @stable ICU 69
125          */
126         YOTTA(24, "yotta", 10),
127 
128         /**
129          * SI prefix: zetta, 10^21.
130          *
131          * @stable ICU 69
132          */
133         ZETTA(21, "zetta", 10),
134 
135         /**
136          * SI prefix: exa, 10^18.
137          *
138          * @stable ICU 69
139          */
140         EXA(18, "exa", 10),
141 
142         /**
143          * SI prefix: peta, 10^15.
144          *
145          * @stable ICU 69
146          */
147         PETA(15, "peta", 10),
148 
149         /**
150          * SI prefix: tera, 10^12.
151          *
152          * @stable ICU 69
153          */
154         TERA(12, "tera", 10),
155 
156         /**
157          * SI prefix: giga, 10^9.
158          *
159          * @stable ICU 69
160          */
161         GIGA(9, "giga", 10),
162 
163         /**
164          * SI prefix: mega, 10^6.
165          *
166          * @stable ICU 69
167          */
168         MEGA(6, "mega", 10),
169 
170         /**
171          * SI prefix: kilo, 10^3.
172          *
173          * @stable ICU 69
174          */
175         KILO(3, "kilo", 10),
176 
177         /**
178          * SI prefix: hecto, 10^2.
179          *
180          * @stable ICU 69
181          */
182         HECTO(2, "hecto", 10),
183 
184         /**
185          * SI prefix: deka, 10^1.
186          *
187          * @stable ICU 69
188          */
189         DEKA(1, "deka", 10),
190 
191         /**
192          * The absence of an SI prefix.
193          *
194          * @stable ICU 69
195          */
196         ONE(0, "", 10),
197 
198         /**
199          * SI prefix: deci, 10^-1.
200          *
201          * @stable ICU 69
202          */
203         DECI(-1, "deci", 10),
204 
205         /**
206          * SI prefix: centi, 10^-2.
207          *
208          * @stable ICU 69
209          */
210         CENTI(-2, "centi", 10),
211 
212         /**
213          * SI prefix: milli, 10^-3.
214          *
215          * @stable ICU 69
216          */
217         MILLI(-3, "milli", 10),
218 
219         /**
220          * SI prefix: micro, 10^-6.
221          *
222          * @stable ICU 69
223          */
224         MICRO(-6, "micro", 10),
225 
226         /**
227          * SI prefix: nano, 10^-9.
228          *
229          * @stable ICU 69
230          */
231         NANO(-9, "nano", 10),
232 
233         /**
234          * SI prefix: pico, 10^-12.
235          *
236          * @stable ICU 69
237          */
238         PICO(-12, "pico", 10),
239 
240         /**
241          * SI prefix: femto, 10^-15.
242          *
243          * @stable ICU 69
244          */
245         FEMTO(-15, "femto", 10),
246 
247         /**
248          * SI prefix: atto, 10^-18.
249          *
250          * @stable ICU 69
251          */
252         ATTO(-18, "atto", 10),
253 
254         /**
255          * SI prefix: zepto, 10^-21.
256          *
257          * @stable ICU 69
258          */
259         ZEPTO(-21, "zepto", 10),
260 
261         /**
262          * SI prefix: yocto, 10^-24.
263          *
264          * @stable ICU 69
265          */
266         YOCTO(-24, "yocto", 10),
267 
268         /**
269          * IEC binary prefix: kibi, 1024^1.
270          *
271          * @stable ICU 69
272          */
273         KIBI(1, "kibi", 1024),
274 
275         /**
276          * IEC binary prefix: mebi, 1024^2.
277          *
278          * @stable ICU 69
279          */
280         MEBI(2, "mebi", 1024),
281 
282         /**
283          * IEC binary prefix: gibi, 1024^3.
284          *
285          * @stable ICU 69
286          */
287         GIBI(3, "gibi", 1024),
288 
289         /**
290          * IEC binary prefix: tebi, 1024^4.
291          *
292          * @stable ICU 69
293          */
294         TEBI(4, "tebi", 1024),
295 
296         /**
297          * IEC binary prefix: pebi, 1024^5.
298          *
299          * @stable ICU 69
300          */
301         PEBI(5, "pebi", 1024),
302 
303         /**
304          * IEC binary prefix: exbi, 1024^6.
305          *
306          * @stable ICU 69
307          */
308         EXBI(6, "exbi", 1024),
309 
310         /**
311          * IEC binary prefix: zebi, 1024^7.
312          *
313          * @stable ICU 69
314          */
315         ZEBI(7, "zebi", 1024),
316 
317         /**
318          * IEC binary prefix: yobi, 1024^8.
319          *
320          * @stable ICU 69
321          */
322         YOBI(8, "yobi", 1024);
323 
324         private final int base;
325         private final int power;
326         private final String identifier;
327 
MeasurePrefix(int power, String identifier, int base)328         MeasurePrefix(int power, String identifier, int base) {
329             this.base = base;
330             this.power = power;
331             this.identifier = identifier;
332         }
333 
334         /**
335          * Returns the identifier of the prefix.
336          *
337          * @internal
338          * @deprecated This API is ICU internal only.
339          */
340         @Deprecated
getIdentifier()341         public String getIdentifier() {
342             return identifier;
343         }
344 
345         /**
346          * Returns the base of the prefix. For example:
347          * - if the prefix is "centi", the base will be 10.
348          * - if the prefix is "gibi", the base will be 1024.
349          *
350          * @stable ICU 69
351          */
getBase()352         public int getBase() {
353             return base;
354         }
355 
356         /**
357          * Returns the power of the prefix. For example:
358          * - if the prefix is "centi", the power will be -2.
359          * - if the prefix is "gibi", the power will be 3 (for base 1024).
360          *
361          * @stable ICU 69
362          */
getPower()363         public int getPower() {
364             return power;
365         }
366     }
367 
368     /**
369      * @internal
370      * @deprecated This API is ICU internal only.
371      */
372     @Deprecated
MeasureUnit(String type, String subType)373     protected MeasureUnit(String type, String subType) {
374         this.type = type;
375         this.subType = subType;
376     }
377 
378     /**
379      * Construct a MeasureUnit from a CLDR Core Unit Identifier, defined in UTS
380      * 35. (Core unit identifiers and mixed unit identifiers are supported, long
381      * unit identifiers are not.) Validates and canonicalizes the identifier.
382      *
383      * Note: dimensionless <code>MeasureUnit</code> is <code>null</code>
384      *
385      * <pre>
386      * MeasureUnit example = MeasureUnit::forIdentifier("furlong-per-nanosecond")
387      * </pre>
388      *
389      * @param identifier CLDR Unit Identifier
390      * @throws IllegalArgumentException if the identifier is invalid.
391      * @stable ICU 68
392      */
forIdentifier(String identifier)393     public static MeasureUnit forIdentifier(String identifier) {
394         if (identifier == null || identifier.isEmpty()) {
395             return NoUnit.BASE;
396         }
397 
398         return MeasureUnitImpl.forIdentifier(identifier).build();
399     }
400 
401     /**
402      * @internal
403      * @deprecated Internal API for ICU use only.
404      */
405     @Deprecated
fromMeasureUnitImpl(MeasureUnitImpl measureUnitImpl)406     public static MeasureUnit fromMeasureUnitImpl(MeasureUnitImpl measureUnitImpl) {
407         measureUnitImpl.serialize();
408         String identifier = measureUnitImpl.getIdentifier();
409         MeasureUnit result = MeasureUnit.findBySubType(identifier);
410         if (result != null) {
411             return result;
412         }
413 
414         return new MeasureUnit(measureUnitImpl);
415     }
416 
MeasureUnit(MeasureUnitImpl measureUnitImpl)417     private MeasureUnit(MeasureUnitImpl measureUnitImpl) {
418         type = null;
419         subType = null;
420         this.measureUnitImpl = measureUnitImpl.copy();
421     }
422 
423 
424 
425     /**
426      * Get the type, such as "length". May return null.
427      *
428      * @stable ICU 53
429      */
getType()430     public String getType() {
431         return type;
432     }
433 
434 
435     /**
436      * Get the subType, such as “foot”. May return null.
437      *
438      * @stable ICU 53
439      */
getSubtype()440     public String getSubtype() {
441         return subType;
442     }
443 
444     /**
445      * Get CLDR Unit Identifier for this MeasureUnit, as defined in UTS 35.
446      *
447      * @return The string form of this unit.
448      * @stable ICU 68
449      */
getIdentifier()450     public String getIdentifier() {
451         String result = measureUnitImpl == null ? getSubtype() : measureUnitImpl.getIdentifier();
452         return result == null ? "" : result;
453     }
454 
455     /**
456      * Compute the complexity of the unit. See Complexity for more information.
457      *
458      * @return The unit complexity.
459      * @stable ICU 68
460      */
getComplexity()461     public Complexity getComplexity() {
462         if (measureUnitImpl == null) {
463             return MeasureUnitImpl.forIdentifier(getIdentifier()).getComplexity();
464         }
465 
466         return measureUnitImpl.getComplexity();
467     }
468 
469     /**
470      * Creates a MeasureUnit which is this SINGLE unit augmented with the specified prefix.
471      * For example, MeasurePrefix.KILO for "kilo", or MeasurePrefix.KIBI for "kibi".
472      * May return `this` if this unit already has that prefix.
473      * <p>
474      * There is sufficient locale data to format all standard prefixes.
475      * <p>
476      * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an error will
477      * occur. For more information, see `Complexity`.
478      *
479      * @param prefix The prefix, from MeasurePrefix.
480      * @return A new SINGLE unit.
481      * @throws UnsupportedOperationException if this unit is a COMPOUND or MIXED unit.
482      * @stable ICU 69
483      */
withPrefix(MeasurePrefix prefix)484     public MeasureUnit withPrefix(MeasurePrefix prefix) {
485         SingleUnitImpl singleUnit = getSingleUnitImpl();
486         singleUnit.setPrefix(prefix);
487         return singleUnit.build();
488     }
489 
490     /**
491      * Returns the current SI or binary prefix of this SINGLE unit. For example,
492      * if the unit has the prefix "kilo", then MeasurePrefix.KILO is returned.
493      * <p>
494      * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an
495      * error will occur. For more information, see `Complexity`.
496      *
497      * @return The prefix of this SINGLE unit, from MeasurePrefix.
498      * @throws UnsupportedOperationException if the unit is COMPOUND or MIXED.
499      * @stable ICU 69
500      */
getPrefix()501     public MeasurePrefix getPrefix() {
502         return getSingleUnitImpl().getPrefix();
503     }
504 
505     /**
506      * Returns the dimensionality (power) of this MeasureUnit. For example, if the unit is square,
507      * then 2 is returned.
508      * <p>
509      * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an exception will be thrown.
510      * For more information, see `Complexity`.
511      *
512      * @return The dimensionality (power) of this simple unit.
513      * @throws UnsupportedOperationException if the unit is COMPOUND or MIXED.
514      * @stable ICU 68
515      */
getDimensionality()516     public int getDimensionality() {
517         return getSingleUnitImpl().getDimensionality();
518     }
519 
520     /**
521      * Creates a MeasureUnit which is this SINGLE unit augmented with the specified dimensionality
522      * (power). For example, if dimensionality is 2, the unit will be squared.
523      * <p>
524      * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an exception is thrown.
525      * For more information, see `Complexity`.
526      *
527      * @param dimensionality The dimensionality (power).
528      * @return A new SINGLE unit.
529      * @throws UnsupportedOperationException if the unit is COMPOUND or MIXED.
530      * @stable ICU 68
531      */
withDimensionality(int dimensionality)532     public MeasureUnit withDimensionality(int dimensionality) {
533         SingleUnitImpl singleUnit = getSingleUnitImpl();
534         singleUnit.setDimensionality(dimensionality);
535         return singleUnit.build();
536     }
537 
538     /**
539      * Computes the reciprocal of this MeasureUnit, with the numerator and denominator flipped.
540      * <p>
541      * For example, if the receiver is "meter-per-second", the unit "second-per-meter" is returned.
542      * <p>
543      * NOTE: Only works on SINGLE and COMPOUND units. If this is a MIXED unit, an error will
544      * occur. For more information, see `Complexity`.
545      *
546      * @return The reciprocal of the target unit.
547      * @throws UnsupportedOperationException if the unit is MIXED.
548      * @stable ICU 68
549      */
reciprocal()550     public MeasureUnit reciprocal() {
551         MeasureUnitImpl measureUnit = getCopyOfMeasureUnitImpl();
552         measureUnit.takeReciprocal();
553         return measureUnit.build();
554     }
555 
556     /**
557      * Computes the product of this unit with another unit. This is a way to build units from
558      * constituent parts.
559      * <p>
560      * The numerator and denominator are preserved through this operation.
561      * <p>
562      * For example, if the receiver is "kilowatt" and the argument is "hour-per-day", then the
563      * unit "kilowatt-hour-per-day" is returned.
564      * <p>
565      * NOTE: Only works on SINGLE and COMPOUND units. If either unit (receivee and argument) is a
566      * MIXED unit, an error will occur. For more information, see `Complexity`.
567      *
568      * @param other The MeasureUnit to multiply with the target.
569      * @return The product of the target unit with the provided unit.
570      * @throws UnsupportedOperationException if the unit is MIXED.
571      * @stable ICU 68
572      */
product(MeasureUnit other)573     public MeasureUnit product(MeasureUnit other) {
574         MeasureUnitImpl implCopy = getCopyOfMeasureUnitImpl();
575 
576         if (other == null /* dimensionless */) {
577             return implCopy.build();
578         }
579 
580         final MeasureUnitImpl otherImplRef = other.getMaybeReferenceOfMeasureUnitImpl();
581         if (implCopy.getComplexity() == Complexity.MIXED || otherImplRef.getComplexity() == Complexity.MIXED) {
582             throw new UnsupportedOperationException();
583         }
584 
585         for (SingleUnitImpl singleUnit :
586                 otherImplRef.getSingleUnits()) {
587             implCopy.appendSingleUnit(singleUnit);
588         }
589 
590         return implCopy.build();
591     }
592 
593     /**
594      * Returns the list of SINGLE units contained within a sequence of COMPOUND units.
595      * <p>
596      * Examples:
597      * - Given "meter-kilogram-per-second", three units will be returned: "meter",
598      * "kilogram", and "per-second".
599      * - Given "hour+minute+second", three units will be returned: "hour", "minute",
600      * and "second".
601      * <p>
602      * If this is a SINGLE unit, a list of length 1 will be returned.
603      *
604      * @return An unmodifiable list of single units
605      * @stable ICU 68
606      */
splitToSingleUnits()607     public List<MeasureUnit> splitToSingleUnits() {
608         final ArrayList<SingleUnitImpl> singleUnits =
609             getMaybeReferenceOfMeasureUnitImpl().getSingleUnits();
610         List<MeasureUnit> result = new ArrayList<>(singleUnits.size());
611         for (SingleUnitImpl singleUnit : singleUnits) {
612             result.add(singleUnit.build());
613         }
614 
615         return result;
616     }
617 
618     /**
619      * {@inheritDoc}
620      *
621      * @stable ICU 3.0
622      */
623     @Override
hashCode()624     public int hashCode() {
625         return 31 * type.hashCode() + subType.hashCode();
626     }
627 
628     /**
629      * {@inheritDoc}
630      *
631      * @stable ICU 3.0
632      */
633     @Override
equals(Object rhs)634     public boolean equals(Object rhs) {
635         if (rhs == this) {
636             return true;
637         }
638         if (!(rhs instanceof MeasureUnit)) {
639             return false;
640         }
641 
642         return this.getIdentifier().equals(((MeasureUnit) rhs).getIdentifier());
643     }
644 
645     /**
646      * {@inheritDoc}
647      *
648      * @stable ICU 3.0
649      */
650     @Override
toString()651     public String toString() {
652         String result = measureUnitImpl == null ? type + "-" + subType : measureUnitImpl.getIdentifier();
653         return result == null ? "" : result;
654     }
655 
656     /**
657      * Get all of the available units' types. Returned set is unmodifiable.
658      *
659      * @stable ICU 53
660      */
getAvailableTypes()661     public static Set<String> getAvailableTypes() {
662         populateCache();
663         return Collections.unmodifiableSet(cache.keySet());
664     }
665 
666     /**
667      * For the given type, return the available units.
668      * @param type the type
669      * @return the available units for type. Returned set is unmodifiable.
670      * @stable ICU 53
671      */
getAvailable(String type)672     public static Set<MeasureUnit> getAvailable(String type) {
673         populateCache();
674         Map<String, MeasureUnit> units = cache.get(type);
675         // Train users not to modify returned set from the start giving us more
676         // flexibility for implementation.
677         // Use CollectionSet instead of HashSet for better performance.
678         return units == null ? Collections.<MeasureUnit>emptySet()
679                 : Collections.unmodifiableSet(new CollectionSet<>(units.values()));
680     }
681 
682     /**
683      * Get all of the available units. Returned set is unmodifiable.
684      *
685      * @stable ICU 53
686      */
getAvailable()687     public synchronized static Set<MeasureUnit> getAvailable() {
688         Set<MeasureUnit> result = new HashSet<>();
689         for (String type : new HashSet<>(MeasureUnit.getAvailableTypes())) {
690             for (MeasureUnit unit : MeasureUnit.getAvailable(type)) {
691                 result.add(unit);
692             }
693         }
694         // Train users not to modify returned set from the start giving us more
695         // flexibility for implementation.
696         return Collections.unmodifiableSet(result);
697     }
698 
699     /**
700      * Creates a MeasureUnit instance (creates a singleton instance) or returns one from the cache.
701      * <p>
702      * Normally this method should not be used, since there will be no formatting data
703      * available for it, and it may not be returned by getAvailable().
704      * However, for special purposes (such as CLDR tooling), it is available.
705      *
706      * @internal
707      * @deprecated This API is ICU internal only.
708      */
709     @Deprecated
internalGetInstance(String type, String subType)710     public static MeasureUnit internalGetInstance(String type, String subType) {
711         if (type == null || subType == null) {
712             throw new NullPointerException("Type and subType must be non-null");
713         }
714         if (!"currency".equals(type)) {
715             if (!ASCII.containsAll(type) || !ASCII_HYPHEN_DIGITS.containsAll(subType)) {
716                 throw new IllegalArgumentException("The type or subType are invalid.");
717             }
718         }
719         Factory factory;
720         if ("currency".equals(type)) {
721             factory = CURRENCY_FACTORY;
722         } else if ("duration".equals(type)) {
723             factory = TIMEUNIT_FACTORY;
724         } else {
725             factory = UNIT_FACTORY;
726         }
727         return MeasureUnit.addUnit(type, subType, factory);
728     }
729 
730     /**
731      * @internal
732      * @deprecated This API is ICU internal only.
733      */
734     @Deprecated
findBySubType(String subType)735     public static MeasureUnit findBySubType(String subType) {
736         populateCache();
737         for (Map<String, MeasureUnit> unitsForType : cache.values()) {
738             if (unitsForType.containsKey(subType)) {
739                 return unitsForType.get(subType);
740             }
741         }
742         return null;
743     }
744 
745     static final UnicodeSet ASCII = new UnicodeSet('a', 'z').freeze();
746     static final UnicodeSet ASCII_HYPHEN_DIGITS = new UnicodeSet('-', '-', '0', '9', 'a', 'z').freeze();
747 
748     /**
749      * @internal
750      * @deprecated This API is ICU internal only.
751      */
752     @Deprecated
753     protected interface Factory {
754         /**
755          * @internal
756          * @deprecated This API is ICU internal only.
757          */
758         @Deprecated
create(String type, String subType)759         MeasureUnit create(String type, String subType);
760     }
761 
762     private static Factory UNIT_FACTORY = new Factory() {
763         @Override
764         public MeasureUnit create(String type, String subType) {
765             return new MeasureUnit(type, subType);
766         }
767     };
768 
769     static Factory CURRENCY_FACTORY = new Factory() {
770         @Override
771         public MeasureUnit create(String unusedType, String subType) {
772             return new Currency(subType);
773         }
774     };
775 
776     static Factory TIMEUNIT_FACTORY = new Factory() {
777         @Override
778         public MeasureUnit create(String type, String subType) {
779            return new TimeUnit(type, subType);
780         }
781     };
782 
783     /**
784      * Sink for enumerating the available measure units.
785      */
786     private static final class MeasureUnitSink extends UResource.Sink {
787         @Override
put(UResource.Key key, UResource.Value value, boolean noFallback)788         public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
789             UResource.Table unitTypesTable = value.getTable();
790             for (int i2 = 0; unitTypesTable.getKeyAndValue(i2, key, value); ++i2) {
791                 // Skip "compound" and "coordinate" since they are treated differently from the other units
792                 if (key.contentEquals("compound") || key.contentEquals("coordinate")) {
793                     continue;
794                 }
795 
796                 String unitType = key.toString();
797                 UResource.Table unitNamesTable = value.getTable();
798                 for (int i3 = 0; unitNamesTable.getKeyAndValue(i3, key, value); ++i3) {
799                     String unitName = key.toString();
800                     internalGetInstance(unitType, unitName);
801                 }
802             }
803         }
804     }
805 
806     /**
807      * Sink for enumerating the currency numeric codes.
808      */
809     private static final class CurrencyNumericCodeSink extends UResource.Sink {
810         @Override
put(UResource.Key key, UResource.Value value, boolean noFallback)811         public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
812             UResource.Table codesTable = value.getTable();
813             for (int i1 = 0; codesTable.getKeyAndValue(i1, key, value); ++i1) {
814                 internalGetInstance("currency", key.toString());
815             }
816         }
817     }
818 
819     /**
820      * Populate the MeasureUnit cache with all types from the data.
821      * Population is done lazily, in response to MeasureUnit.getAvailable()
822      * or other API that expects to see all of the MeasureUnits.
823      *
824      * <p>At static initialization time the MeasureUnits cache is populated
825      * with public static instances (G_FORCE, METER_PER_SECOND_SQUARED, etc.) only.
826      * Adding of others is deferred until later to avoid circular static init
827      * dependencies with classes Currency and TimeUnit.
828      *
829      * @internal
830      */
populateCache()831     static synchronized private void populateCache() {
832         if (cacheIsPopulated) {
833             return;
834         }
835         cacheIsPopulated = true;
836 
837         /*  Schema:
838          *
839          *  units{
840          *    duration{
841          *      day{
842          *        one{"{0} ден"}
843          *        other{"{0} дена"}
844          *      }
845          */
846 
847         // Load the unit types.  Use English, since we know that that is a superset.
848         ICUResourceBundle rb1 = (ICUResourceBundle) UResourceBundle.getBundleInstance(
849                 ICUData.ICU_UNIT_BASE_NAME,
850                 "en");
851         rb1.getAllItemsWithFallback("units", new MeasureUnitSink());
852 
853         // Load the currencies
854         ICUResourceBundle rb2 = (ICUResourceBundle) UResourceBundle.getBundleInstance(
855                 ICUData.ICU_BASE_NAME,
856                 "currencyNumericCodes",
857                 ICUResourceBundle.ICU_DATA_CLASS_LOADER);
858         rb2.getAllItemsWithFallback("codeMap", new CurrencyNumericCodeSink());
859     }
860 
861     /**
862      * @internal
863      * @deprecated This API is ICU internal only.
864      */
865     @Deprecated
addUnit(String type, String unitName, Factory factory)866     protected synchronized static MeasureUnit addUnit(String type, String unitName, Factory factory) {
867         Map<String, MeasureUnit> tmp = cache.get(type);
868         if (tmp == null) {
869             cache.put(type, tmp = new HashMap<>());
870         } else {
871             // "intern" the type by setting to first item's type.
872             type = tmp.entrySet().iterator().next().getValue().type;
873         }
874         MeasureUnit unit = tmp.get(unitName);
875         if (unit == null) {
876             tmp.put(unitName, unit = factory.create(type, unitName));
877         }
878         return unit;
879     }
880 
881 
882     /*
883      * Useful constants. Not necessarily complete: see {@link #getAvailable()}.
884      */
885 
886 // All code between the "Start generated MeasureUnit constants" comment and
887 // the "End generated MeasureUnit constants" comment is auto generated code
888 // and must not be edited manually. For instructions on how to correctly
889 // update this code, refer to:
890 // docs/processes/release/tasks/updating-measure-unit.md
891 //
892     // Start generated MeasureUnit constants
893 
894     /**
895      * Constant for unit of acceleration: g-force
896      * @stable ICU 53
897      */
898     public static final MeasureUnit G_FORCE = MeasureUnit.internalGetInstance("acceleration", "g-force");
899 
900     /**
901      * Constant for unit of acceleration: meter-per-square-second
902      * @stable ICU 54
903      */
904     public static final MeasureUnit METER_PER_SECOND_SQUARED = MeasureUnit.internalGetInstance("acceleration", "meter-per-square-second");
905 
906     /**
907      * Constant for unit of angle: arc-minute
908      * @stable ICU 53
909      */
910     public static final MeasureUnit ARC_MINUTE = MeasureUnit.internalGetInstance("angle", "arc-minute");
911 
912     /**
913      * Constant for unit of angle: arc-second
914      * @stable ICU 53
915      */
916     public static final MeasureUnit ARC_SECOND = MeasureUnit.internalGetInstance("angle", "arc-second");
917 
918     /**
919      * Constant for unit of angle: degree
920      * @stable ICU 53
921      */
922     public static final MeasureUnit DEGREE = MeasureUnit.internalGetInstance("angle", "degree");
923 
924     /**
925      * Constant for unit of angle: radian
926      * @stable ICU 54
927      */
928     public static final MeasureUnit RADIAN = MeasureUnit.internalGetInstance("angle", "radian");
929 
930     /**
931      * Constant for unit of angle: revolution
932      * @stable ICU 56
933      */
934     public static final MeasureUnit REVOLUTION_ANGLE = MeasureUnit.internalGetInstance("angle", "revolution");
935 
936     /**
937      * Constant for unit of area: acre
938      * @stable ICU 53
939      */
940     public static final MeasureUnit ACRE = MeasureUnit.internalGetInstance("area", "acre");
941 
942     /**
943      * Constant for unit of area: dunam
944      * @stable ICU 64
945      */
946     public static final MeasureUnit DUNAM = MeasureUnit.internalGetInstance("area", "dunam");
947 
948     /**
949      * Constant for unit of area: hectare
950      * @stable ICU 53
951      */
952     public static final MeasureUnit HECTARE = MeasureUnit.internalGetInstance("area", "hectare");
953 
954     /**
955      * Constant for unit of area: square-centimeter
956      * @stable ICU 54
957      */
958     public static final MeasureUnit SQUARE_CENTIMETER = MeasureUnit.internalGetInstance("area", "square-centimeter");
959 
960     /**
961      * Constant for unit of area: square-foot
962      * @stable ICU 53
963      */
964     public static final MeasureUnit SQUARE_FOOT = MeasureUnit.internalGetInstance("area", "square-foot");
965 
966     /**
967      * Constant for unit of area: square-inch
968      * @stable ICU 54
969      */
970     public static final MeasureUnit SQUARE_INCH = MeasureUnit.internalGetInstance("area", "square-inch");
971 
972     /**
973      * Constant for unit of area: square-kilometer
974      * @stable ICU 53
975      */
976     public static final MeasureUnit SQUARE_KILOMETER = MeasureUnit.internalGetInstance("area", "square-kilometer");
977 
978     /**
979      * Constant for unit of area: square-meter
980      * @stable ICU 53
981      */
982     public static final MeasureUnit SQUARE_METER = MeasureUnit.internalGetInstance("area", "square-meter");
983 
984     /**
985      * Constant for unit of area: square-mile
986      * @stable ICU 53
987      */
988     public static final MeasureUnit SQUARE_MILE = MeasureUnit.internalGetInstance("area", "square-mile");
989 
990     /**
991      * Constant for unit of area: square-yard
992      * @stable ICU 54
993      */
994     public static final MeasureUnit SQUARE_YARD = MeasureUnit.internalGetInstance("area", "square-yard");
995 
996     /**
997      * Constant for unit of concentr: item
998      * @stable ICU 70
999      */
1000     public static final MeasureUnit ITEM = MeasureUnit.internalGetInstance("concentr", "item");
1001 
1002     /**
1003      * Constant for unit of concentr: karat
1004      * @stable ICU 54
1005      */
1006     public static final MeasureUnit KARAT = MeasureUnit.internalGetInstance("concentr", "karat");
1007 
1008     /**
1009      * Constant for unit of concentr: milligram-ofglucose-per-deciliter
1010      * @stable ICU 69
1011      */
1012     public static final MeasureUnit MILLIGRAM_OFGLUCOSE_PER_DECILITER = MeasureUnit.internalGetInstance("concentr", "milligram-ofglucose-per-deciliter");
1013 
1014     /**
1015      * Constant for unit of concentr: milligram-per-deciliter
1016      * @stable ICU 57
1017      */
1018     public static final MeasureUnit MILLIGRAM_PER_DECILITER = MeasureUnit.internalGetInstance("concentr", "milligram-per-deciliter");
1019 
1020     /**
1021      * Constant for unit of concentr: millimole-per-liter
1022      * @stable ICU 57
1023      */
1024     public static final MeasureUnit MILLIMOLE_PER_LITER = MeasureUnit.internalGetInstance("concentr", "millimole-per-liter");
1025 
1026     /**
1027      * Constant for unit of concentr: mole
1028      * @stable ICU 64
1029      */
1030     public static final MeasureUnit MOLE = MeasureUnit.internalGetInstance("concentr", "mole");
1031 
1032     /**
1033      * Constant for unit of concentr: percent
1034      * @stable ICU 63
1035      */
1036     public static final MeasureUnit PERCENT = MeasureUnit.internalGetInstance("concentr", "percent");
1037 
1038     /**
1039      * Constant for unit of concentr: permille
1040      * @stable ICU 63
1041      */
1042     public static final MeasureUnit PERMILLE = MeasureUnit.internalGetInstance("concentr", "permille");
1043 
1044     /**
1045      * Constant for unit of concentr: permillion
1046      * @stable ICU 57
1047      */
1048     public static final MeasureUnit PART_PER_MILLION = MeasureUnit.internalGetInstance("concentr", "permillion");
1049 
1050     /**
1051      * Constant for unit of concentr: permyriad
1052      * @stable ICU 64
1053      */
1054     public static final MeasureUnit PERMYRIAD = MeasureUnit.internalGetInstance("concentr", "permyriad");
1055 
1056     /**
1057      * Constant for unit of consumption: liter-per-100-kilometer
1058      * @stable ICU 56
1059      */
1060     public static final MeasureUnit LITER_PER_100KILOMETERS = MeasureUnit.internalGetInstance("consumption", "liter-per-100-kilometer");
1061 
1062     /**
1063      * Constant for unit of consumption: liter-per-kilometer
1064      * @stable ICU 54
1065      */
1066     public static final MeasureUnit LITER_PER_KILOMETER = MeasureUnit.internalGetInstance("consumption", "liter-per-kilometer");
1067 
1068     /**
1069      * Constant for unit of consumption: mile-per-gallon
1070      * @stable ICU 54
1071      */
1072     public static final MeasureUnit MILE_PER_GALLON = MeasureUnit.internalGetInstance("consumption", "mile-per-gallon");
1073 
1074     /**
1075      * Constant for unit of consumption: mile-per-gallon-imperial
1076      * @stable ICU 57
1077      */
1078     public static final MeasureUnit MILE_PER_GALLON_IMPERIAL = MeasureUnit.internalGetInstance("consumption", "mile-per-gallon-imperial");
1079 
1080     /**
1081      * Constant for unit of digital: bit
1082      * @stable ICU 54
1083      */
1084     public static final MeasureUnit BIT = MeasureUnit.internalGetInstance("digital", "bit");
1085 
1086     /**
1087      * Constant for unit of digital: byte
1088      * @stable ICU 54
1089      */
1090     public static final MeasureUnit BYTE = MeasureUnit.internalGetInstance("digital", "byte");
1091 
1092     /**
1093      * Constant for unit of digital: gigabit
1094      * @stable ICU 54
1095      */
1096     public static final MeasureUnit GIGABIT = MeasureUnit.internalGetInstance("digital", "gigabit");
1097 
1098     /**
1099      * Constant for unit of digital: gigabyte
1100      * @stable ICU 54
1101      */
1102     public static final MeasureUnit GIGABYTE = MeasureUnit.internalGetInstance("digital", "gigabyte");
1103 
1104     /**
1105      * Constant for unit of digital: kilobit
1106      * @stable ICU 54
1107      */
1108     public static final MeasureUnit KILOBIT = MeasureUnit.internalGetInstance("digital", "kilobit");
1109 
1110     /**
1111      * Constant for unit of digital: kilobyte
1112      * @stable ICU 54
1113      */
1114     public static final MeasureUnit KILOBYTE = MeasureUnit.internalGetInstance("digital", "kilobyte");
1115 
1116     /**
1117      * Constant for unit of digital: megabit
1118      * @stable ICU 54
1119      */
1120     public static final MeasureUnit MEGABIT = MeasureUnit.internalGetInstance("digital", "megabit");
1121 
1122     /**
1123      * Constant for unit of digital: megabyte
1124      * @stable ICU 54
1125      */
1126     public static final MeasureUnit MEGABYTE = MeasureUnit.internalGetInstance("digital", "megabyte");
1127 
1128     /**
1129      * Constant for unit of digital: petabyte
1130      * @stable ICU 63
1131      */
1132     public static final MeasureUnit PETABYTE = MeasureUnit.internalGetInstance("digital", "petabyte");
1133 
1134     /**
1135      * Constant for unit of digital: terabit
1136      * @stable ICU 54
1137      */
1138     public static final MeasureUnit TERABIT = MeasureUnit.internalGetInstance("digital", "terabit");
1139 
1140     /**
1141      * Constant for unit of digital: terabyte
1142      * @stable ICU 54
1143      */
1144     public static final MeasureUnit TERABYTE = MeasureUnit.internalGetInstance("digital", "terabyte");
1145 
1146     /**
1147      * Constant for unit of duration: century
1148      * @stable ICU 56
1149      */
1150     public static final MeasureUnit CENTURY = MeasureUnit.internalGetInstance("duration", "century");
1151 
1152     /**
1153      * Constant for unit of duration: day
1154      * @stable ICU 4.0
1155      */
1156     public static final TimeUnit DAY = (TimeUnit) MeasureUnit.internalGetInstance("duration", "day");
1157 
1158     /**
1159      * Constant for unit of duration: day-person
1160      * @stable ICU 64
1161      */
1162     public static final MeasureUnit DAY_PERSON = MeasureUnit.internalGetInstance("duration", "day-person");
1163 
1164     /**
1165      * Constant for unit of duration: decade
1166      * @stable ICU 65
1167      */
1168     public static final MeasureUnit DECADE = MeasureUnit.internalGetInstance("duration", "decade");
1169 
1170     /**
1171      * Constant for unit of duration: hour
1172      * @stable ICU 4.0
1173      */
1174     public static final TimeUnit HOUR = (TimeUnit) MeasureUnit.internalGetInstance("duration", "hour");
1175 
1176     /**
1177      * Constant for unit of duration: microsecond
1178      * @stable ICU 54
1179      */
1180     public static final MeasureUnit MICROSECOND = MeasureUnit.internalGetInstance("duration", "microsecond");
1181 
1182     /**
1183      * Constant for unit of duration: millisecond
1184      * @stable ICU 53
1185      */
1186     public static final MeasureUnit MILLISECOND = MeasureUnit.internalGetInstance("duration", "millisecond");
1187 
1188     /**
1189      * Constant for unit of duration: minute
1190      * @stable ICU 4.0
1191      */
1192     public static final TimeUnit MINUTE = (TimeUnit) MeasureUnit.internalGetInstance("duration", "minute");
1193 
1194     /**
1195      * Constant for unit of duration: month
1196      * @stable ICU 4.0
1197      */
1198     public static final TimeUnit MONTH = (TimeUnit) MeasureUnit.internalGetInstance("duration", "month");
1199 
1200     /**
1201      * Constant for unit of duration: month-person
1202      * @stable ICU 64
1203      */
1204     public static final MeasureUnit MONTH_PERSON = MeasureUnit.internalGetInstance("duration", "month-person");
1205 
1206     /**
1207      * Constant for unit of duration: nanosecond
1208      * @stable ICU 54
1209      */
1210     public static final MeasureUnit NANOSECOND = MeasureUnit.internalGetInstance("duration", "nanosecond");
1211 
1212     /**
1213      * Constant for unit of duration: quarter
1214      * @draft ICU 72
1215      */
1216     public static final MeasureUnit QUARTER = MeasureUnit.internalGetInstance("duration", "quarter");
1217 
1218     /**
1219      * Constant for unit of duration: second
1220      * @stable ICU 4.0
1221      */
1222     public static final TimeUnit SECOND = (TimeUnit) MeasureUnit.internalGetInstance("duration", "second");
1223 
1224     /**
1225      * Constant for unit of duration: week
1226      * @stable ICU 4.0
1227      */
1228     public static final TimeUnit WEEK = (TimeUnit) MeasureUnit.internalGetInstance("duration", "week");
1229 
1230     /**
1231      * Constant for unit of duration: week-person
1232      * @stable ICU 64
1233      */
1234     public static final MeasureUnit WEEK_PERSON = MeasureUnit.internalGetInstance("duration", "week-person");
1235 
1236     /**
1237      * Constant for unit of duration: year
1238      * @stable ICU 4.0
1239      */
1240     public static final TimeUnit YEAR = (TimeUnit) MeasureUnit.internalGetInstance("duration", "year");
1241 
1242     /**
1243      * Constant for unit of duration: year-person
1244      * @stable ICU 64
1245      */
1246     public static final MeasureUnit YEAR_PERSON = MeasureUnit.internalGetInstance("duration", "year-person");
1247 
1248     /**
1249      * Constant for unit of electric: ampere
1250      * @stable ICU 54
1251      */
1252     public static final MeasureUnit AMPERE = MeasureUnit.internalGetInstance("electric", "ampere");
1253 
1254     /**
1255      * Constant for unit of electric: milliampere
1256      * @stable ICU 54
1257      */
1258     public static final MeasureUnit MILLIAMPERE = MeasureUnit.internalGetInstance("electric", "milliampere");
1259 
1260     /**
1261      * Constant for unit of electric: ohm
1262      * @stable ICU 54
1263      */
1264     public static final MeasureUnit OHM = MeasureUnit.internalGetInstance("electric", "ohm");
1265 
1266     /**
1267      * Constant for unit of electric: volt
1268      * @stable ICU 54
1269      */
1270     public static final MeasureUnit VOLT = MeasureUnit.internalGetInstance("electric", "volt");
1271 
1272     /**
1273      * Constant for unit of energy: british-thermal-unit
1274      * @stable ICU 64
1275      */
1276     public static final MeasureUnit BRITISH_THERMAL_UNIT = MeasureUnit.internalGetInstance("energy", "british-thermal-unit");
1277 
1278     /**
1279      * Constant for unit of energy: calorie
1280      * @stable ICU 54
1281      */
1282     public static final MeasureUnit CALORIE = MeasureUnit.internalGetInstance("energy", "calorie");
1283 
1284     /**
1285      * Constant for unit of energy: electronvolt
1286      * @stable ICU 64
1287      */
1288     public static final MeasureUnit ELECTRONVOLT = MeasureUnit.internalGetInstance("energy", "electronvolt");
1289 
1290     /**
1291      * Constant for unit of energy: foodcalorie
1292      * @stable ICU 54
1293      */
1294     public static final MeasureUnit FOODCALORIE = MeasureUnit.internalGetInstance("energy", "foodcalorie");
1295 
1296     /**
1297      * Constant for unit of energy: joule
1298      * @stable ICU 54
1299      */
1300     public static final MeasureUnit JOULE = MeasureUnit.internalGetInstance("energy", "joule");
1301 
1302     /**
1303      * Constant for unit of energy: kilocalorie
1304      * @stable ICU 54
1305      */
1306     public static final MeasureUnit KILOCALORIE = MeasureUnit.internalGetInstance("energy", "kilocalorie");
1307 
1308     /**
1309      * Constant for unit of energy: kilojoule
1310      * @stable ICU 54
1311      */
1312     public static final MeasureUnit KILOJOULE = MeasureUnit.internalGetInstance("energy", "kilojoule");
1313 
1314     /**
1315      * Constant for unit of energy: kilowatt-hour
1316      * @stable ICU 54
1317      */
1318     public static final MeasureUnit KILOWATT_HOUR = MeasureUnit.internalGetInstance("energy", "kilowatt-hour");
1319 
1320     /**
1321      * Constant for unit of energy: therm-us
1322      * @stable ICU 65
1323      */
1324     public static final MeasureUnit THERM_US = MeasureUnit.internalGetInstance("energy", "therm-us");
1325 
1326     /**
1327      * Constant for unit of force: kilowatt-hour-per-100-kilometer
1328      * @stable ICU 70
1329      */
1330     public static final MeasureUnit KILOWATT_HOUR_PER_100_KILOMETER = MeasureUnit.internalGetInstance("force", "kilowatt-hour-per-100-kilometer");
1331 
1332     /**
1333      * Constant for unit of force: newton
1334      * @stable ICU 64
1335      */
1336     public static final MeasureUnit NEWTON = MeasureUnit.internalGetInstance("force", "newton");
1337 
1338     /**
1339      * Constant for unit of force: pound-force
1340      * @stable ICU 64
1341      */
1342     public static final MeasureUnit POUND_FORCE = MeasureUnit.internalGetInstance("force", "pound-force");
1343 
1344     /**
1345      * Constant for unit of frequency: gigahertz
1346      * @stable ICU 54
1347      */
1348     public static final MeasureUnit GIGAHERTZ = MeasureUnit.internalGetInstance("frequency", "gigahertz");
1349 
1350     /**
1351      * Constant for unit of frequency: hertz
1352      * @stable ICU 54
1353      */
1354     public static final MeasureUnit HERTZ = MeasureUnit.internalGetInstance("frequency", "hertz");
1355 
1356     /**
1357      * Constant for unit of frequency: kilohertz
1358      * @stable ICU 54
1359      */
1360     public static final MeasureUnit KILOHERTZ = MeasureUnit.internalGetInstance("frequency", "kilohertz");
1361 
1362     /**
1363      * Constant for unit of frequency: megahertz
1364      * @stable ICU 54
1365      */
1366     public static final MeasureUnit MEGAHERTZ = MeasureUnit.internalGetInstance("frequency", "megahertz");
1367 
1368     /**
1369      * Constant for unit of graphics: dot
1370      * @stable ICU 68
1371      */
1372     public static final MeasureUnit DOT = MeasureUnit.internalGetInstance("graphics", "dot");
1373 
1374     /**
1375      * Constant for unit of graphics: dot-per-centimeter
1376      * @stable ICU 65
1377      */
1378     public static final MeasureUnit DOT_PER_CENTIMETER = MeasureUnit.internalGetInstance("graphics", "dot-per-centimeter");
1379 
1380     /**
1381      * Constant for unit of graphics: dot-per-inch
1382      * @stable ICU 65
1383      */
1384     public static final MeasureUnit DOT_PER_INCH = MeasureUnit.internalGetInstance("graphics", "dot-per-inch");
1385 
1386     /**
1387      * Constant for unit of graphics: em
1388      * @stable ICU 65
1389      */
1390     public static final MeasureUnit EM = MeasureUnit.internalGetInstance("graphics", "em");
1391 
1392     /**
1393      * Constant for unit of graphics: megapixel
1394      * @stable ICU 65
1395      */
1396     public static final MeasureUnit MEGAPIXEL = MeasureUnit.internalGetInstance("graphics", "megapixel");
1397 
1398     /**
1399      * Constant for unit of graphics: pixel
1400      * @stable ICU 65
1401      */
1402     public static final MeasureUnit PIXEL = MeasureUnit.internalGetInstance("graphics", "pixel");
1403 
1404     /**
1405      * Constant for unit of graphics: pixel-per-centimeter
1406      * @stable ICU 65
1407      */
1408     public static final MeasureUnit PIXEL_PER_CENTIMETER = MeasureUnit.internalGetInstance("graphics", "pixel-per-centimeter");
1409 
1410     /**
1411      * Constant for unit of graphics: pixel-per-inch
1412      * @stable ICU 65
1413      */
1414     public static final MeasureUnit PIXEL_PER_INCH = MeasureUnit.internalGetInstance("graphics", "pixel-per-inch");
1415 
1416     /**
1417      * Constant for unit of length: astronomical-unit
1418      * @stable ICU 54
1419      */
1420     public static final MeasureUnit ASTRONOMICAL_UNIT = MeasureUnit.internalGetInstance("length", "astronomical-unit");
1421 
1422     /**
1423      * Constant for unit of length: centimeter
1424      * @stable ICU 53
1425      */
1426     public static final MeasureUnit CENTIMETER = MeasureUnit.internalGetInstance("length", "centimeter");
1427 
1428     /**
1429      * Constant for unit of length: decimeter
1430      * @stable ICU 54
1431      */
1432     public static final MeasureUnit DECIMETER = MeasureUnit.internalGetInstance("length", "decimeter");
1433 
1434     /**
1435      * Constant for unit of length: earth-radius
1436      * @stable ICU 68
1437      */
1438     public static final MeasureUnit EARTH_RADIUS = MeasureUnit.internalGetInstance("length", "earth-radius");
1439 
1440     /**
1441      * Constant for unit of length: fathom
1442      * @stable ICU 54
1443      */
1444     public static final MeasureUnit FATHOM = MeasureUnit.internalGetInstance("length", "fathom");
1445 
1446     /**
1447      * Constant for unit of length: foot
1448      * @stable ICU 53
1449      */
1450     public static final MeasureUnit FOOT = MeasureUnit.internalGetInstance("length", "foot");
1451 
1452     /**
1453      * Constant for unit of length: furlong
1454      * @stable ICU 54
1455      */
1456     public static final MeasureUnit FURLONG = MeasureUnit.internalGetInstance("length", "furlong");
1457 
1458     /**
1459      * Constant for unit of length: inch
1460      * @stable ICU 53
1461      */
1462     public static final MeasureUnit INCH = MeasureUnit.internalGetInstance("length", "inch");
1463 
1464     /**
1465      * Constant for unit of length: kilometer
1466      * @stable ICU 53
1467      */
1468     public static final MeasureUnit KILOMETER = MeasureUnit.internalGetInstance("length", "kilometer");
1469 
1470     /**
1471      * Constant for unit of length: light-year
1472      * @stable ICU 53
1473      */
1474     public static final MeasureUnit LIGHT_YEAR = MeasureUnit.internalGetInstance("length", "light-year");
1475 
1476     /**
1477      * Constant for unit of length: meter
1478      * @stable ICU 53
1479      */
1480     public static final MeasureUnit METER = MeasureUnit.internalGetInstance("length", "meter");
1481 
1482     /**
1483      * Constant for unit of length: micrometer
1484      * @stable ICU 54
1485      */
1486     public static final MeasureUnit MICROMETER = MeasureUnit.internalGetInstance("length", "micrometer");
1487 
1488     /**
1489      * Constant for unit of length: mile
1490      * @stable ICU 53
1491      */
1492     public static final MeasureUnit MILE = MeasureUnit.internalGetInstance("length", "mile");
1493 
1494     /**
1495      * Constant for unit of length: mile-scandinavian
1496      * @stable ICU 56
1497      */
1498     public static final MeasureUnit MILE_SCANDINAVIAN = MeasureUnit.internalGetInstance("length", "mile-scandinavian");
1499 
1500     /**
1501      * Constant for unit of length: millimeter
1502      * @stable ICU 53
1503      */
1504     public static final MeasureUnit MILLIMETER = MeasureUnit.internalGetInstance("length", "millimeter");
1505 
1506     /**
1507      * Constant for unit of length: nanometer
1508      * @stable ICU 54
1509      */
1510     public static final MeasureUnit NANOMETER = MeasureUnit.internalGetInstance("length", "nanometer");
1511 
1512     /**
1513      * Constant for unit of length: nautical-mile
1514      * @stable ICU 54
1515      */
1516     public static final MeasureUnit NAUTICAL_MILE = MeasureUnit.internalGetInstance("length", "nautical-mile");
1517 
1518     /**
1519      * Constant for unit of length: parsec
1520      * @stable ICU 54
1521      */
1522     public static final MeasureUnit PARSEC = MeasureUnit.internalGetInstance("length", "parsec");
1523 
1524     /**
1525      * Constant for unit of length: picometer
1526      * @stable ICU 53
1527      */
1528     public static final MeasureUnit PICOMETER = MeasureUnit.internalGetInstance("length", "picometer");
1529 
1530     /**
1531      * Constant for unit of length: point
1532      * @stable ICU 59
1533      */
1534     public static final MeasureUnit POINT = MeasureUnit.internalGetInstance("length", "point");
1535 
1536     /**
1537      * Constant for unit of length: solar-radius
1538      * @stable ICU 64
1539      */
1540     public static final MeasureUnit SOLAR_RADIUS = MeasureUnit.internalGetInstance("length", "solar-radius");
1541 
1542     /**
1543      * Constant for unit of length: yard
1544      * @stable ICU 53
1545      */
1546     public static final MeasureUnit YARD = MeasureUnit.internalGetInstance("length", "yard");
1547 
1548     /**
1549      * Constant for unit of light: candela
1550      * @stable ICU 68
1551      */
1552     public static final MeasureUnit CANDELA = MeasureUnit.internalGetInstance("light", "candela");
1553 
1554     /**
1555      * Constant for unit of light: lumen
1556      * @stable ICU 68
1557      */
1558     public static final MeasureUnit LUMEN = MeasureUnit.internalGetInstance("light", "lumen");
1559 
1560     /**
1561      * Constant for unit of light: lux
1562      * @stable ICU 54
1563      */
1564     public static final MeasureUnit LUX = MeasureUnit.internalGetInstance("light", "lux");
1565 
1566     /**
1567      * Constant for unit of light: solar-luminosity
1568      * @stable ICU 64
1569      */
1570     public static final MeasureUnit SOLAR_LUMINOSITY = MeasureUnit.internalGetInstance("light", "solar-luminosity");
1571 
1572     /**
1573      * Constant for unit of mass: carat
1574      * @stable ICU 54
1575      */
1576     public static final MeasureUnit CARAT = MeasureUnit.internalGetInstance("mass", "carat");
1577 
1578     /**
1579      * Constant for unit of mass: dalton
1580      * @stable ICU 64
1581      */
1582     public static final MeasureUnit DALTON = MeasureUnit.internalGetInstance("mass", "dalton");
1583 
1584     /**
1585      * Constant for unit of mass: earth-mass
1586      * @stable ICU 64
1587      */
1588     public static final MeasureUnit EARTH_MASS = MeasureUnit.internalGetInstance("mass", "earth-mass");
1589 
1590     /**
1591      * Constant for unit of mass: grain
1592      * @stable ICU 68
1593      */
1594     public static final MeasureUnit GRAIN = MeasureUnit.internalGetInstance("mass", "grain");
1595 
1596     /**
1597      * Constant for unit of mass: gram
1598      * @stable ICU 53
1599      */
1600     public static final MeasureUnit GRAM = MeasureUnit.internalGetInstance("mass", "gram");
1601 
1602     /**
1603      * Constant for unit of mass: kilogram
1604      * @stable ICU 53
1605      */
1606     public static final MeasureUnit KILOGRAM = MeasureUnit.internalGetInstance("mass", "kilogram");
1607 
1608     /**
1609      * Constant for unit of mass: metric-ton (renamed to tonne in CLDR 42 / ICU 72).
1610      * Note: In ICU 74 this will be deprecated in favor of TONNE, which is currently
1611      * draft but will become stable in ICU 74, and which uses the preferred naming.
1612      * @stable ICU 54
1613      */
1614     public static final MeasureUnit METRIC_TON = MeasureUnit.internalGetInstance("mass", "tonne");
1615 
1616     /**
1617      * Constant for unit of mass: microgram
1618      * @stable ICU 54
1619      */
1620     public static final MeasureUnit MICROGRAM = MeasureUnit.internalGetInstance("mass", "microgram");
1621 
1622     /**
1623      * Constant for unit of mass: milligram
1624      * @stable ICU 54
1625      */
1626     public static final MeasureUnit MILLIGRAM = MeasureUnit.internalGetInstance("mass", "milligram");
1627 
1628     /**
1629      * Constant for unit of mass: ounce
1630      * @stable ICU 53
1631      */
1632     public static final MeasureUnit OUNCE = MeasureUnit.internalGetInstance("mass", "ounce");
1633 
1634     /**
1635      * Constant for unit of mass: ounce-troy
1636      * @stable ICU 54
1637      */
1638     public static final MeasureUnit OUNCE_TROY = MeasureUnit.internalGetInstance("mass", "ounce-troy");
1639 
1640     /**
1641      * Constant for unit of mass: pound
1642      * @stable ICU 53
1643      */
1644     public static final MeasureUnit POUND = MeasureUnit.internalGetInstance("mass", "pound");
1645 
1646     /**
1647      * Constant for unit of mass: solar-mass
1648      * @stable ICU 64
1649      */
1650     public static final MeasureUnit SOLAR_MASS = MeasureUnit.internalGetInstance("mass", "solar-mass");
1651 
1652     /**
1653      * Constant for unit of mass: stone
1654      * @stable ICU 54
1655      */
1656     public static final MeasureUnit STONE = MeasureUnit.internalGetInstance("mass", "stone");
1657 
1658     /**
1659      * Constant for unit of mass: ton
1660      * @stable ICU 54
1661      */
1662     public static final MeasureUnit TON = MeasureUnit.internalGetInstance("mass", "ton");
1663 
1664     /**
1665      * Constant for unit of mass: tonne
1666      * @draft ICU 72
1667      */
1668     public static final MeasureUnit TONNE = MeasureUnit.internalGetInstance("mass", "tonne");
1669 
1670     /**
1671      * Constant for unit of power: gigawatt
1672      * @stable ICU 54
1673      */
1674     public static final MeasureUnit GIGAWATT = MeasureUnit.internalGetInstance("power", "gigawatt");
1675 
1676     /**
1677      * Constant for unit of power: horsepower
1678      * @stable ICU 53
1679      */
1680     public static final MeasureUnit HORSEPOWER = MeasureUnit.internalGetInstance("power", "horsepower");
1681 
1682     /**
1683      * Constant for unit of power: kilowatt
1684      * @stable ICU 53
1685      */
1686     public static final MeasureUnit KILOWATT = MeasureUnit.internalGetInstance("power", "kilowatt");
1687 
1688     /**
1689      * Constant for unit of power: megawatt
1690      * @stable ICU 54
1691      */
1692     public static final MeasureUnit MEGAWATT = MeasureUnit.internalGetInstance("power", "megawatt");
1693 
1694     /**
1695      * Constant for unit of power: milliwatt
1696      * @stable ICU 54
1697      */
1698     public static final MeasureUnit MILLIWATT = MeasureUnit.internalGetInstance("power", "milliwatt");
1699 
1700     /**
1701      * Constant for unit of power: watt
1702      * @stable ICU 53
1703      */
1704     public static final MeasureUnit WATT = MeasureUnit.internalGetInstance("power", "watt");
1705 
1706     /**
1707      * Constant for unit of pressure: atmosphere
1708      * @stable ICU 63
1709      */
1710     public static final MeasureUnit ATMOSPHERE = MeasureUnit.internalGetInstance("pressure", "atmosphere");
1711 
1712     /**
1713      * Constant for unit of pressure: bar
1714      * @stable ICU 65
1715      */
1716     public static final MeasureUnit BAR = MeasureUnit.internalGetInstance("pressure", "bar");
1717 
1718     /**
1719      * Constant for unit of pressure: hectopascal
1720      * @stable ICU 53
1721      */
1722     public static final MeasureUnit HECTOPASCAL = MeasureUnit.internalGetInstance("pressure", "hectopascal");
1723 
1724     /**
1725      * Constant for unit of pressure: inch-ofhg
1726      * @stable ICU 53
1727      */
1728     public static final MeasureUnit INCH_HG = MeasureUnit.internalGetInstance("pressure", "inch-ofhg");
1729 
1730     /**
1731      * Constant for unit of pressure: kilopascal
1732      * @stable ICU 64
1733      */
1734     public static final MeasureUnit KILOPASCAL = MeasureUnit.internalGetInstance("pressure", "kilopascal");
1735 
1736     /**
1737      * Constant for unit of pressure: megapascal
1738      * @stable ICU 64
1739      */
1740     public static final MeasureUnit MEGAPASCAL = MeasureUnit.internalGetInstance("pressure", "megapascal");
1741 
1742     /**
1743      * Constant for unit of pressure: millibar
1744      * @stable ICU 53
1745      */
1746     public static final MeasureUnit MILLIBAR = MeasureUnit.internalGetInstance("pressure", "millibar");
1747 
1748     /**
1749      * Constant for unit of pressure: millimeter-ofhg
1750      * @stable ICU 54
1751      */
1752     public static final MeasureUnit MILLIMETER_OF_MERCURY = MeasureUnit.internalGetInstance("pressure", "millimeter-ofhg");
1753 
1754     /**
1755      * Constant for unit of pressure: pascal
1756      * @stable ICU 65
1757      */
1758     public static final MeasureUnit PASCAL = MeasureUnit.internalGetInstance("pressure", "pascal");
1759 
1760     /**
1761      * Constant for unit of pressure: pound-force-per-square-inch
1762      * @stable ICU 54
1763      */
1764     public static final MeasureUnit POUND_PER_SQUARE_INCH = MeasureUnit.internalGetInstance("pressure", "pound-force-per-square-inch");
1765 
1766     /**
1767      * Constant for unit of speed: kilometer-per-hour
1768      * @stable ICU 53
1769      */
1770     public static final MeasureUnit KILOMETER_PER_HOUR = MeasureUnit.internalGetInstance("speed", "kilometer-per-hour");
1771 
1772     /**
1773      * Constant for unit of speed: knot
1774      * @stable ICU 56
1775      */
1776     public static final MeasureUnit KNOT = MeasureUnit.internalGetInstance("speed", "knot");
1777 
1778     /**
1779      * Constant for unit of speed: meter-per-second
1780      * @stable ICU 53
1781      */
1782     public static final MeasureUnit METER_PER_SECOND = MeasureUnit.internalGetInstance("speed", "meter-per-second");
1783 
1784     /**
1785      * Constant for unit of speed: mile-per-hour
1786      * @stable ICU 53
1787      */
1788     public static final MeasureUnit MILE_PER_HOUR = MeasureUnit.internalGetInstance("speed", "mile-per-hour");
1789 
1790     /**
1791      * Constant for unit of temperature: celsius
1792      * @stable ICU 53
1793      */
1794     public static final MeasureUnit CELSIUS = MeasureUnit.internalGetInstance("temperature", "celsius");
1795 
1796     /**
1797      * Constant for unit of temperature: fahrenheit
1798      * @stable ICU 53
1799      */
1800     public static final MeasureUnit FAHRENHEIT = MeasureUnit.internalGetInstance("temperature", "fahrenheit");
1801 
1802     /**
1803      * Constant for unit of temperature: generic
1804      * @stable ICU 56
1805      */
1806     public static final MeasureUnit GENERIC_TEMPERATURE = MeasureUnit.internalGetInstance("temperature", "generic");
1807 
1808     /**
1809      * Constant for unit of temperature: kelvin
1810      * @stable ICU 54
1811      */
1812     public static final MeasureUnit KELVIN = MeasureUnit.internalGetInstance("temperature", "kelvin");
1813 
1814     /**
1815      * Constant for unit of torque: newton-meter
1816      * @stable ICU 64
1817      */
1818     public static final MeasureUnit NEWTON_METER = MeasureUnit.internalGetInstance("torque", "newton-meter");
1819 
1820     /**
1821      * Constant for unit of torque: pound-force-foot
1822      * @stable ICU 64
1823      */
1824     public static final MeasureUnit POUND_FOOT = MeasureUnit.internalGetInstance("torque", "pound-force-foot");
1825 
1826     /**
1827      * Constant for unit of volume: acre-foot
1828      * @stable ICU 54
1829      */
1830     public static final MeasureUnit ACRE_FOOT = MeasureUnit.internalGetInstance("volume", "acre-foot");
1831 
1832     /**
1833      * Constant for unit of volume: barrel
1834      * @stable ICU 64
1835      */
1836     public static final MeasureUnit BARREL = MeasureUnit.internalGetInstance("volume", "barrel");
1837 
1838     /**
1839      * Constant for unit of volume: bushel
1840      * @stable ICU 54
1841      */
1842     public static final MeasureUnit BUSHEL = MeasureUnit.internalGetInstance("volume", "bushel");
1843 
1844     /**
1845      * Constant for unit of volume: centiliter
1846      * @stable ICU 54
1847      */
1848     public static final MeasureUnit CENTILITER = MeasureUnit.internalGetInstance("volume", "centiliter");
1849 
1850     /**
1851      * Constant for unit of volume: cubic-centimeter
1852      * @stable ICU 54
1853      */
1854     public static final MeasureUnit CUBIC_CENTIMETER = MeasureUnit.internalGetInstance("volume", "cubic-centimeter");
1855 
1856     /**
1857      * Constant for unit of volume: cubic-foot
1858      * @stable ICU 54
1859      */
1860     public static final MeasureUnit CUBIC_FOOT = MeasureUnit.internalGetInstance("volume", "cubic-foot");
1861 
1862     /**
1863      * Constant for unit of volume: cubic-inch
1864      * @stable ICU 54
1865      */
1866     public static final MeasureUnit CUBIC_INCH = MeasureUnit.internalGetInstance("volume", "cubic-inch");
1867 
1868     /**
1869      * Constant for unit of volume: cubic-kilometer
1870      * @stable ICU 53
1871      */
1872     public static final MeasureUnit CUBIC_KILOMETER = MeasureUnit.internalGetInstance("volume", "cubic-kilometer");
1873 
1874     /**
1875      * Constant for unit of volume: cubic-meter
1876      * @stable ICU 54
1877      */
1878     public static final MeasureUnit CUBIC_METER = MeasureUnit.internalGetInstance("volume", "cubic-meter");
1879 
1880     /**
1881      * Constant for unit of volume: cubic-mile
1882      * @stable ICU 53
1883      */
1884     public static final MeasureUnit CUBIC_MILE = MeasureUnit.internalGetInstance("volume", "cubic-mile");
1885 
1886     /**
1887      * Constant for unit of volume: cubic-yard
1888      * @stable ICU 54
1889      */
1890     public static final MeasureUnit CUBIC_YARD = MeasureUnit.internalGetInstance("volume", "cubic-yard");
1891 
1892     /**
1893      * Constant for unit of volume: cup
1894      * @stable ICU 54
1895      */
1896     public static final MeasureUnit CUP = MeasureUnit.internalGetInstance("volume", "cup");
1897 
1898     /**
1899      * Constant for unit of volume: cup-metric
1900      * @stable ICU 56
1901      */
1902     public static final MeasureUnit CUP_METRIC = MeasureUnit.internalGetInstance("volume", "cup-metric");
1903 
1904     /**
1905      * Constant for unit of volume: deciliter
1906      * @stable ICU 54
1907      */
1908     public static final MeasureUnit DECILITER = MeasureUnit.internalGetInstance("volume", "deciliter");
1909 
1910     /**
1911      * Constant for unit of volume: dessert-spoon
1912      * @stable ICU 68
1913      */
1914     public static final MeasureUnit DESSERT_SPOON = MeasureUnit.internalGetInstance("volume", "dessert-spoon");
1915 
1916     /**
1917      * Constant for unit of volume: dessert-spoon-imperial
1918      * @stable ICU 68
1919      */
1920     public static final MeasureUnit DESSERT_SPOON_IMPERIAL = MeasureUnit.internalGetInstance("volume", "dessert-spoon-imperial");
1921 
1922     /**
1923      * Constant for unit of volume: dram
1924      * @stable ICU 68
1925      */
1926     public static final MeasureUnit DRAM = MeasureUnit.internalGetInstance("volume", "dram");
1927 
1928     /**
1929      * Constant for unit of volume: drop
1930      * @stable ICU 68
1931      */
1932     public static final MeasureUnit DROP = MeasureUnit.internalGetInstance("volume", "drop");
1933 
1934     /**
1935      * Constant for unit of volume: fluid-ounce
1936      * @stable ICU 54
1937      */
1938     public static final MeasureUnit FLUID_OUNCE = MeasureUnit.internalGetInstance("volume", "fluid-ounce");
1939 
1940     /**
1941      * Constant for unit of volume: fluid-ounce-imperial
1942      * @stable ICU 64
1943      */
1944     public static final MeasureUnit FLUID_OUNCE_IMPERIAL = MeasureUnit.internalGetInstance("volume", "fluid-ounce-imperial");
1945 
1946     /**
1947      * Constant for unit of volume: gallon
1948      * @stable ICU 54
1949      */
1950     public static final MeasureUnit GALLON = MeasureUnit.internalGetInstance("volume", "gallon");
1951 
1952     /**
1953      * Constant for unit of volume: gallon-imperial
1954      * @stable ICU 57
1955      */
1956     public static final MeasureUnit GALLON_IMPERIAL = MeasureUnit.internalGetInstance("volume", "gallon-imperial");
1957 
1958     /**
1959      * Constant for unit of volume: hectoliter
1960      * @stable ICU 54
1961      */
1962     public static final MeasureUnit HECTOLITER = MeasureUnit.internalGetInstance("volume", "hectoliter");
1963 
1964     /**
1965      * Constant for unit of volume: jigger
1966      * @stable ICU 68
1967      */
1968     public static final MeasureUnit JIGGER = MeasureUnit.internalGetInstance("volume", "jigger");
1969 
1970     /**
1971      * Constant for unit of volume: liter
1972      * @stable ICU 53
1973      */
1974     public static final MeasureUnit LITER = MeasureUnit.internalGetInstance("volume", "liter");
1975 
1976     /**
1977      * Constant for unit of volume: megaliter
1978      * @stable ICU 54
1979      */
1980     public static final MeasureUnit MEGALITER = MeasureUnit.internalGetInstance("volume", "megaliter");
1981 
1982     /**
1983      * Constant for unit of volume: milliliter
1984      * @stable ICU 54
1985      */
1986     public static final MeasureUnit MILLILITER = MeasureUnit.internalGetInstance("volume", "milliliter");
1987 
1988     /**
1989      * Constant for unit of volume: pinch
1990      * @stable ICU 68
1991      */
1992     public static final MeasureUnit PINCH = MeasureUnit.internalGetInstance("volume", "pinch");
1993 
1994     /**
1995      * Constant for unit of volume: pint
1996      * @stable ICU 54
1997      */
1998     public static final MeasureUnit PINT = MeasureUnit.internalGetInstance("volume", "pint");
1999 
2000     /**
2001      * Constant for unit of volume: pint-metric
2002      * @stable ICU 56
2003      */
2004     public static final MeasureUnit PINT_METRIC = MeasureUnit.internalGetInstance("volume", "pint-metric");
2005 
2006     /**
2007      * Constant for unit of volume: quart
2008      * @stable ICU 54
2009      */
2010     public static final MeasureUnit QUART = MeasureUnit.internalGetInstance("volume", "quart");
2011 
2012     /**
2013      * Constant for unit of volume: quart-imperial
2014      * @stable ICU 68
2015      */
2016     public static final MeasureUnit QUART_IMPERIAL = MeasureUnit.internalGetInstance("volume", "quart-imperial");
2017 
2018     /**
2019      * Constant for unit of volume: tablespoon
2020      * @stable ICU 54
2021      */
2022     public static final MeasureUnit TABLESPOON = MeasureUnit.internalGetInstance("volume", "tablespoon");
2023 
2024     /**
2025      * Constant for unit of volume: teaspoon
2026      * @stable ICU 54
2027      */
2028     public static final MeasureUnit TEASPOON = MeasureUnit.internalGetInstance("volume", "teaspoon");
2029 
2030     // End generated MeasureUnit constants
2031 
2032     /* Private */
2033 
writeReplace()2034     private Object writeReplace() throws ObjectStreamException {
2035         return new MeasureUnitProxy(type, subType);
2036     }
2037 
2038     /**
2039      *
2040      * @return this object as a SingleUnitImpl.
2041      * @throws UnsupportedOperationException if this object could not be converted to a single unit.
2042      */
2043     // In ICU4C, this is SingleUnitImpl::forMeasureUnit().
getSingleUnitImpl()2044     private SingleUnitImpl getSingleUnitImpl() {
2045         if (measureUnitImpl == null) {
2046             return MeasureUnitImpl.forIdentifier(getIdentifier()).getSingleUnitImpl();
2047         }
2048 
2049         return measureUnitImpl.getSingleUnitImpl();
2050     }
2051 
2052     /**
2053      *
2054      * @return this object in a MeasureUnitImpl form.
2055      * @internal
2056      * @deprecated This API is ICU internal only.
2057      */
2058     @Deprecated
getCopyOfMeasureUnitImpl()2059     public MeasureUnitImpl getCopyOfMeasureUnitImpl() {
2060         return this.measureUnitImpl == null ?
2061                 MeasureUnitImpl.forIdentifier(getIdentifier()) :
2062                 this.measureUnitImpl.copy();
2063     }
2064 
2065     /**
2066      *
2067      * @return this object in a MeasureUnitImpl form.
2068      */
getMaybeReferenceOfMeasureUnitImpl()2069     private MeasureUnitImpl getMaybeReferenceOfMeasureUnitImpl() {
2070         return this.measureUnitImpl == null ?
2071                 MeasureUnitImpl.forIdentifier(getIdentifier()) :
2072                 this.measureUnitImpl;
2073     }
2074 
2075     static final class MeasureUnitProxy implements Externalizable {
2076         private static final long serialVersionUID = -3910681415330989598L;
2077 
2078         private String type;
2079         private String subType;
2080 
MeasureUnitProxy(String type, String subType)2081         public MeasureUnitProxy(String type, String subType) {
2082             this.type = type;
2083             this.subType = subType;
2084         }
2085 
2086         // Must have public constructor, to enable Externalizable
MeasureUnitProxy()2087         public MeasureUnitProxy() {
2088         }
2089 
2090         @Override
writeExternal(ObjectOutput out)2091         public void writeExternal(ObjectOutput out) throws IOException {
2092             out.writeByte(0); // version
2093             out.writeUTF(type);
2094             out.writeUTF(subType);
2095             out.writeShort(0); // allow for more data.
2096         }
2097 
2098         @Override
readExternal(ObjectInput in)2099         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
2100             /* byte version = */ in.readByte(); // version
2101             type = in.readUTF();
2102             subType = in.readUTF();
2103             // allow for more data from future version
2104             int extra = in.readShort();
2105             if (extra > 0) {
2106                 byte[] extraBytes = new byte[extra];
2107                 in.read(extraBytes, 0, extra);
2108             }
2109         }
2110 
readResolve()2111         private Object readResolve() throws ObjectStreamException {
2112             return MeasureUnit.internalGetInstance(type, subType);
2113         }
2114     }
2115 }
2116