FileDocCategorySizeDatePackage
Currency.javaAPI DocJava SE 6 API17131Tue Jun 10 00:25:52 BST 2008java.util

Currency

public final class Currency extends Object implements Serializable
Represents a currency. Currencies are identified by their ISO 4217 currency codes. Visit the BSi web site for more information, including a table of currency codes.

The class is designed so that there's never more than one Currency instance for any given currency. Therefore, there's no public constructor. You obtain a Currency instance using the getInstance methods.

since
1.4

Fields Summary
private static final long
serialVersionUID
private final String
currencyCode
ISO 4217 currency code for this currency.
private final transient int
defaultFractionDigits
Default fraction digits for this currency. Set from currency data tables.
private static HashMap
instances
static String
mainTable
static long[]
scCutOverTimes
static String[]
scOldCurrencies
static String[]
scNewCurrencies
static int[]
scOldCurrenciesDFD
static int[]
scNewCurrenciesDFD
static String
otherCurrencies
static int[]
otherCurrenciesDFD
private static final int
A_TO_Z
private static final int
INVALID_COUNTRY_ENTRY
private static final int
COUNTRY_WITHOUT_CURRENCY_ENTRY
private static final int
SIMPLE_CASE_COUNTRY_MASK
private static final int
SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK
private static final int
SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK
private static final int
SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT
private static final int
SPECIAL_CASE_COUNTRY_MASK
private static final int
SPECIAL_CASE_COUNTRY_INDEX_MASK
private static final int
SPECIAL_CASE_COUNTRY_INDEX_DELTA
private static final int
COUNTRY_TYPE_MASK
Constructors Summary
private Currency(String currencyCode, int defaultFractionDigits)
Constructs a Currency instance. The constructor is private so that we can insure that there's never more than one instance for a given currency.


     
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                try {
                    Class data = Class.forName("java.util.CurrencyData");
                    mainTable = (String) data.getDeclaredField("mainTable").get(data);
                    scCutOverTimes = (long[]) data.getDeclaredField("scCutOverTimes").get(data);
                    scOldCurrencies = (String[]) data.getDeclaredField("scOldCurrencies").get(data);
                    scNewCurrencies = (String[]) data.getDeclaredField("scNewCurrencies").get(data);
                    scOldCurrenciesDFD = (int[]) data.getDeclaredField("scOldCurrenciesDFD").get(data);
                    scNewCurrenciesDFD = (int[]) data.getDeclaredField("scNewCurrenciesDFD").get(data);
                    otherCurrencies = (String) data.getDeclaredField("otherCurrencies").get(data);
                    otherCurrenciesDFD = (int[]) data.getDeclaredField("otherCurrenciesDFD").get(data);
                } catch (ClassNotFoundException e) {
                    throw new InternalError();
                } catch (NoSuchFieldException e) {
                    throw new InternalError();
                } catch (IllegalAccessException e) {
                    throw new InternalError();
                }
                return null;
            }
        });
    
        this.currencyCode = currencyCode;
        this.defaultFractionDigits = defaultFractionDigits;
    
Methods Summary
public java.lang.StringgetCurrencyCode()
Gets the ISO 4217 currency code of this currency.

return
the ISO 4217 currency code of this currency.

        return currencyCode;
    
public intgetDefaultFractionDigits()
Gets the default number of fraction digits used with this currency. For example, the default number of fraction digits for the Euro is 2, while for the Japanese Yen it's 0. In the case of pseudo-currencies, such as IMF Special Drawing Rights, -1 is returned.

return
the default number of fraction digits used with this currency

        return defaultFractionDigits;
    
public static java.util.CurrencygetInstance(java.lang.String currencyCode)
Returns the Currency instance for the given currency code.

param
currencyCode the ISO 4217 code of the currency
return
the Currency instance for the given currency code
exception
NullPointerException if currencyCode is null
exception
IllegalArgumentException if currencyCode is not a supported ISO 4217 code.

        return getInstance(currencyCode, Integer.MIN_VALUE);
    
private static java.util.CurrencygetInstance(java.lang.String currencyCode, int defaultFractionDigits)

        synchronized (instances) {
            // Try to look up the currency code in the instances table.
            // This does the null pointer check as a side effect.
            // Also, if there already is an entry, the currencyCode must be valid.
            Currency instance = (Currency) instances.get(currencyCode);
            if (instance != null) {
                return instance;
            }
        
            if (defaultFractionDigits == Integer.MIN_VALUE) {
                // Currency code not internally generated, need to verify first
                // A currency code must have 3 characters and exist in the main table
                // or in the list of other currencies.
                if (currencyCode.length() != 3) {
                    throw new IllegalArgumentException();
                }
                char char1 = currencyCode.charAt(0);
                char char2 = currencyCode.charAt(1);
                int tableEntry = getMainTableEntry(char1, char2);
                if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
                        && tableEntry != INVALID_COUNTRY_ENTRY
                        && currencyCode.charAt(2) - 'A" == (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK)) {
                    defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
                } else {
                    // Check for '-' separately so we don't get false hits in the table.
                    if (currencyCode.charAt(2) == '-") {
                        throw new IllegalArgumentException();
                    }
                    int index = otherCurrencies.indexOf(currencyCode);
                    if (index == -1) {
                        throw new IllegalArgumentException();
                    }
                    defaultFractionDigits = otherCurrenciesDFD[index / 4];
                }
            }
        
            instance = new Currency(currencyCode, defaultFractionDigits);
            instances.put(currencyCode, instance);
            return instance;
        }
    
public static java.util.CurrencygetInstance(java.util.Locale locale)
Returns the Currency instance for the country of the given locale. The language and variant components of the locale are ignored. The result may vary over time, as countries change their currencies. For example, for the original member countries of the European Monetary Union, the method returns the old national currencies until December 31, 2001, and the Euro from January 1, 2002, local time of the respective countries.

The method returns null for territories that don't have a currency, such as Antarctica.

param
locale the locale for whose country a Currency instance is needed
return
the Currency instance for the country of the given locale, or null
exception
NullPointerException if locale or its country code is null
exception
IllegalArgumentException if the country of the given locale is not a supported ISO 3166 country code.

        String country = locale.getCountry();
        if (country == null) {
            throw new NullPointerException();
        }

        if (country.length() != 2) {
            throw new IllegalArgumentException();
        }
        
        char char1 = country.charAt(0);
        char char2 = country.charAt(1);
        int tableEntry = getMainTableEntry(char1, char2);
        if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
                    && tableEntry != INVALID_COUNTRY_ENTRY) {
            char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A");
            int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
            StringBuffer sb = new StringBuffer(country);
            sb.append(finalChar);
            return getInstance(sb.toString(), defaultFractionDigits);
        } else {
            // special cases
            if (tableEntry == INVALID_COUNTRY_ENTRY) {
                throw new IllegalArgumentException();
            }
            if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
                return null;
            } else {
                int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
                if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) {
                    return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index]);
                } else {
                    return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index]);
                }
            }
        }
    
private static intgetMainTableEntry(char char1, char char2)
Gets the main table entry for the country whose country code consists of char1 and char2.

        if (char1 < 'A" || char1 > 'Z" || char2 < 'A" || char2 > 'Z") {
            throw new IllegalArgumentException();
        }
        return mainTable.charAt((char1 - 'A") * A_TO_Z + (char2 - 'A"));
    
public java.lang.StringgetSymbol()
Gets the symbol of this currency for the default locale. For example, for the US Dollar, the symbol is "$" if the default locale is the US, while for other locales it may be "US$". If no symbol can be determined, the ISO 4217 currency code is returned.

return
the symbol of this currency for the default locale

        return getSymbol(Locale.getDefault());
    
public java.lang.StringgetSymbol(java.util.Locale locale)
Gets the symbol of this currency for the specified locale. For example, for the US Dollar, the symbol is "$" if the specified locale is the US, while for other locales it may be "US$". If no symbol can be determined, the ISO 4217 currency code is returned.

param
locale the locale for which a display name for this currency is needed
return
the symbol of this currency for the specified locale
exception
NullPointerException if locale is null

        try {
            // Check whether a provider can provide an implementation that's closer 
            // to the requested locale than what the Java runtime itself can provide.
            LocaleServiceProviderPool pool =
                LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);

            if (pool.hasProviders()) {
                // Assuming that all the country locales include necessary currency 
                // symbols in the Java runtime's resources,  so there is no need to
                // examine whether Java runtime's currency resource bundle is missing 
                // names.  Therefore, no resource bundle is provided for calling this 
                // method.
                String symbol = pool.getLocalizedObject(
                                    CurrencyNameGetter.INSTANCE,
                                    locale, null, currencyCode);
                if (symbol != null) {
                    return symbol;
                }
            }

            ResourceBundle bundle = LocaleData.getCurrencyNames(locale);
            return bundle.getString(currencyCode);
        } catch (MissingResourceException e) {
            // use currency code as symbol of last resort
            return currencyCode;
        }
    
private java.lang.ObjectreadResolve()
Resolves instances being deserialized to a single instance per currency.

        return getInstance(currencyCode);
    
public java.lang.StringtoString()
Returns the ISO 4217 currency code of this currency.

return
the ISO 4217 currency code of this currency

        return currencyCode;