赞
踩
java的NumberFormat、DecimalFormat、MessageFormat类源码详解
NumberFormat类的定义
- public abstract class NumberFormat extends Format {
-
- protected NumberFormat() {
- }
-
- @Override
- public StringBuffer format(Object number,
- StringBuffer toAppendTo,
- FieldPosition pos) {
- if (number instanceof Long || number instanceof Integer ||
- number instanceof Short || number instanceof Byte ||
- number instanceof AtomicInteger || number instanceof AtomicLong ||
- (number instanceof BigInteger &&
- ((BigInteger)number).bitLength() < 64)) {
- return format(((Number)number).longValue(), toAppendTo, pos);
- } else if (number instanceof Number) {
- return format(((Number)number).doubleValue(), toAppendTo, pos);
- } else {
- throw new IllegalArgumentException("Cannot format given Object as a Number");
- }
- }
-
- @Override
- public final Object parseObject(String source, ParsePosition pos) {
- return parse(source, pos);
- }
-
- public final String format(double number) {
- // Use fast-path for double result if that works
- String result = fastFormat(number);
- if (result != null)
- return result;
-
- return format(number, new StringBuffer(),
- DontCareFieldPosition.INSTANCE).toString();
- }
-
-
- String fastFormat(double number) { return null; }
-
- public final String format(long number) {
- return format(number, new StringBuffer(),
- DontCareFieldPosition.INSTANCE).toString();
- }
-
- public abstract StringBuffer format(double number,
- StringBuffer toAppendTo,
- FieldPosition pos);
-
- public abstract StringBuffer format(long number,
- StringBuffer toAppendTo,
- FieldPosition pos);
-
- public abstract Number parse(String source, ParsePosition parsePosition);
-
- public Number parse(String source) throws ParseException {
- ParsePosition parsePosition = new ParsePosition(0);
- Number result = parse(source, parsePosition);
- if (parsePosition.index == 0) {
- throw new ParseException("Unparseable number: \"" + source + "\"",
- parsePosition.errorIndex);
- }
- return result;
- }
-
- public boolean isParseIntegerOnly() {
- return parseIntegerOnly;
- }
-
- public void setParseIntegerOnly(boolean value) {
- parseIntegerOnly = value;
- }
-
- //============== Locale Stuff =====================
- public final static NumberFormat getInstance() {
- return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
- }
-
- public static NumberFormat getInstance(Locale inLocale) {
- return getInstance(inLocale, NUMBERSTYLE);
- }
-
- public final static NumberFormat getNumberInstance() {
- return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
- }
-
- public static NumberFormat getNumberInstance(Locale inLocale) {
- return getInstance(inLocale, NUMBERSTYLE);
- }
-
- public final static NumberFormat getIntegerInstance() {
- return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);
- }
-
- public static NumberFormat getIntegerInstance(Locale inLocale) {
- return getInstance(inLocale, INTEGERSTYLE);
- }
-
- public final static NumberFormat getCurrencyInstance() {
- return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
- }
-
- public static NumberFormat getCurrencyInstance(Locale inLocale) {
- return getInstance(inLocale, CURRENCYSTYLE);
- }
-
- public final static NumberFormat getPercentInstance() {
- return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
- }
-
- public static NumberFormat getPercentInstance(Locale inLocale) {
- return getInstance(inLocale, PERCENTSTYLE);
- }
-
- /*public*/ final static NumberFormat getScientificInstance() {
- return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);
- }
-
- /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
- return getInstance(inLocale, SCIENTIFICSTYLE);
- }
-
- public static Locale[] getAvailableLocales() {
- LocaleServiceProviderPool pool =
- LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
- return pool.getAvailableLocales();
- }
-
- @Override
- public int hashCode() {
- return maximumIntegerDigits * 37 + maxFractionDigits;
- // just enough fields for a reasonable distribution
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (this == obj) {
- return true;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- NumberFormat other = (NumberFormat) obj;
- return (maximumIntegerDigits == other.maximumIntegerDigits
- && minimumIntegerDigits == other.minimumIntegerDigits
- && maximumFractionDigits == other.maximumFractionDigits
- && minimumFractionDigits == other.minimumFractionDigits
- && groupingUsed == other.groupingUsed
- && parseIntegerOnly == other.parseIntegerOnly);
- }
-
- @Override
- public Object clone() {
- NumberFormat other = (NumberFormat) super.clone();
- return other;
- }
- }
- import java.text.* ;
- public class NumberFormatDemo01{
- public static void main(String args[]){
- NumberFormat nf = null ; // 声明一个NumberFormat对象
- nf = NumberFormat.getInstance() ; // 得到默认的数字格式化显示
- System.out.println("格式化之后的数字:" + nf.format(10000000)) ;
- System.out.println("格式化之后的数字:" + nf.format(1000.345)) ;
- }
- };
import java.text.NumberFormat;
1。Decimalformat df1 = new Decimalformat("####.000");
System.out.println(df1.format(1234.56));
显示:1234.560
2。NumberFormat nf = NumberFormat.getPercentInstance();
// nf.setMinimumFractionDigits( 2 ); 保留到小数点后几位 显示:47.00%
System.out.println(nf.format(0.47));
显示:47%
(法二)
DecimalFormat df1 = new DecimalFormat("##.00%"); //##.00% 百分比格式,后面不足2位的用0补齐
baifenbi= df1.format(fen);
显示:47.00%
3。DecimalFormat df = new DecimalFormat("###,##0.00");
System.out.println(nf.format(24.7));
显示:24.70
System.out.println(nf.format(23123.47));
显示:123,23.47
补充:0.00、0.01; 0.00%、0.12%这样的数据,如果按照上面的格式可能会造成数据显示成:.00、.01; .00%、.12%,怎么办呢?只要把格式改成:
DecimalFormat df1 = new DecimalFormat("0.00");
DecimalFormat df2 = new DecimalFormat("0.00%");
df1.formatI(number);df2.formatI(number);
显示:0.00、0.01; 0.00%、0.12%
- public class Test {
- public static void main(String[] args) {
- Double myNumber=23323.3323232323;
- Double test=0.3434;
- //getInstance()
- //返回当前缺省语言环境的缺省数值格式。
- String myString = NumberFormat.getInstance().format(myNumber);
- System.out.println(myString);
- //getCurrencyInstance()返回当前缺省语言环境的通用格式
- myString = NumberFormat.getCurrencyInstance().format(myNumber);
- System.out.println(myString);
- //getNumberInstance() 返回当前缺省语言环境的通用数值格式。
- myString = NumberFormat.getNumberInstance().format(myNumber);
- System.out.println(myString);
- //getPercentInstance() 返回当前缺省语言环境的百分比格式。
- myString = NumberFormat.getPercentInstance().format(test);
- System.out.println(myString);
- //setMaximumFractionDigits(int) 设置数值的小数部分允许的最大位数。
- //setMaximumIntegerDigits(int) 设置数值的整数部分允许的最大位数。
- //setMinimumFractionDigits(int) 设置数值的小数部分允许的最小位数。
- //setMinimumIntegerDigits(int) 设置数值的整数部分允许的最小位数.
- NumberFormat format = NumberFormat.getInstance();
- format.setMinimumFractionDigits( 3 );
- format.setMaximumFractionDigits(5);
- format.setMaximumIntegerDigits( 10 );
- format.setMinimumIntegerDigits(0);
- System.out.println(format.format(2132323213.23266666666));
- }
-
- }
结果为:
23,323.332
¥23,323.33
23,323.332
34%
2,132,323,213.23267
MessageFormat
- public class MessageFormat extends Format {
-
- private static final long serialVersionUID = 6479157306784022952L;
-
- public MessageFormat(String pattern) {
- this.locale = Locale.getDefault(Locale.Category.FORMAT);
- applyPattern(pattern);
- }
-
- public MessageFormat(String pattern, Locale locale) {
- this.locale = locale;
- applyPattern(pattern);
- }
-
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- public Locale getLocale() {
- return locale;
- }
-
- @SuppressWarnings("fallthrough") // fallthrough in switch is expected, suppress it
- public void applyPattern(String pattern) {
- StringBuilder[] segments = new StringBuilder[4];
- // Allocate only segments[SEG_RAW] here. The rest are
- // allocated on demand.
- segments[SEG_RAW] = new StringBuilder();
-
- int part = SEG_RAW;
- int formatNumber = 0;
- boolean inQuote = false;
- int braceStack = 0;
- maxOffset = -1;
- for (int i = 0; i < pattern.length(); ++i) {
- char ch = pattern.charAt(i);
- if (part == SEG_RAW) {
- if (ch == '\'') {
- if (i + 1 < pattern.length()
- && pattern.charAt(i+1) == '\'') {
- segments[part].append(ch); // handle doubles
- ++i;
- } else {
- inQuote = !inQuote;
- }
- } else if (ch == '{' && !inQuote) {
- part = SEG_INDEX;
- if (segments[SEG_INDEX] == null) {
- segments[SEG_INDEX] = new StringBuilder();
- }
- } else {
- segments[part].append(ch);
- }
- } else {
- if (inQuote) { // just copy quotes in parts
- segments[part].append(ch);
- if (ch == '\'') {
- inQuote = false;
- }
- } else {
- switch (ch) {
- case ',':
- if (part < SEG_MODIFIER) {
- if (segments[++part] == null) {
- segments[part] = new StringBuilder();
- }
- } else {
- segments[part].append(ch);
- }
- break;
- case '{':
- ++braceStack;
- segments[part].append(ch);
- break;
- case '}':
- if (braceStack == 0) {
- part = SEG_RAW;
- makeFormat(i, formatNumber, segments);
- formatNumber++;
- // throw away other segments
- segments[SEG_INDEX] = null;
- segments[SEG_TYPE] = null;
- segments[SEG_MODIFIER] = null;
- } else {
- --braceStack;
- segments[part].append(ch);
- }
- break;
- case ' ':
- // Skip any leading space chars for SEG_TYPE.
- if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) {
- segments[part].append(ch);
- }
- break;
- case '\'':
- inQuote = true;
- // fall through, so we keep quotes in other parts
- default:
- segments[part].append(ch);
- break;
- }
- }
- }
- }
- if (braceStack == 0 && part != 0) {
- maxOffset = -1;
- throw new IllegalArgumentException("Unmatched braces in the pattern.");
- }
- this.pattern = segments[0].toString();
- }
-
- public String toPattern() {
- // later, make this more extensible
- int lastOffset = 0;
- StringBuilder result = new StringBuilder();
- for (int i = 0; i <= maxOffset; ++i) {
- copyAndFixQuotes(pattern, lastOffset, offsets[i], result);
- lastOffset = offsets[i];
- result.append('{').append(argumentNumbers[i]);
- Format fmt = formats[i];
- if (fmt == null) {
- // do nothing, string format
- } else if (fmt instanceof NumberFormat) {
- if (fmt.equals(NumberFormat.getInstance(locale))) {
- result.append(",number");
- } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) {
- result.append(",number,currency");
- } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) {
- result.append(",number,percent");
- } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) {
- result.append(",number,integer");
- } else {
- if (fmt instanceof DecimalFormat) {
- result.append(",number,").append(((DecimalFormat)fmt).toPattern());
- } else if (fmt instanceof ChoiceFormat) {
- result.append(",choice,").append(((ChoiceFormat)fmt).toPattern());
- } else {
- // UNKNOWN
- }
- }
- } else if (fmt instanceof DateFormat) {
- int index;
- for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) {
- DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index],
- locale);
- if (fmt.equals(df)) {
- result.append(",date");
- break;
- }
- df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index],
- locale);
- if (fmt.equals(df)) {
- result.append(",time");
- break;
- }
- }
- if (index >= DATE_TIME_MODIFIERS.length) {
- if (fmt instanceof SimpleDateFormat) {
- result.append(",date,").append(((SimpleDateFormat)fmt).toPattern());
- } else {
- // UNKNOWN
- }
- } else if (index != MODIFIER_DEFAULT) {
- result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]);
- }
- } else {
- //result.append(", unknown");
- }
- result.append('}');
- }
- copyAndFixQuotes(pattern, lastOffset, pattern.length(), result);
- return result.toString();
- }
-
- public final StringBuffer format(Object[] arguments, StringBuffer result,
- FieldPosition pos)
- {
- return subformat(arguments, result, pos, null);
- }
-
- public static String format(String pattern, Object ... arguments) {
- MessageFormat temp = new MessageFormat(pattern);
- return temp.format(arguments);
- }
-
- // Overrides
- public final StringBuffer format(Object arguments, StringBuffer result,
- FieldPosition pos)
- {
- return subformat((Object[]) arguments, result, pos, null);
- }
-
- public Object[] parse(String source, ParsePosition pos) {
- if (source == null) {
- Object[] empty = {};
- return empty;
- }
-
- int maximumArgumentNumber = -1;
- for (int i = 0; i <= maxOffset; i++) {
- if (argumentNumbers[i] > maximumArgumentNumber) {
- maximumArgumentNumber = argumentNumbers[i];
- }
- }
- Object[] resultArray = new Object[maximumArgumentNumber + 1];
-
- int patternOffset = 0;
- int sourceOffset = pos.index;
- ParsePosition tempStatus = new ParsePosition(0);
- for (int i = 0; i <= maxOffset; ++i) {
- // match up to format
- int len = offsets[i] - patternOffset;
- if (len == 0 || pattern.regionMatches(patternOffset,
- source, sourceOffset, len)) {
- sourceOffset += len;
- patternOffset += len;
- } else {
- pos.errorIndex = sourceOffset;
- return null; // leave index as is to signal error
- }
-
- // now use format
- if (formats[i] == null) { // string format
- // if at end, use longest possible match
- // otherwise uses first match to intervening string
- // does NOT recursively try all possibilities
- int tempLength = (i != maxOffset) ? offsets[i+1] : pattern.length();
-
- int next;
- if (patternOffset >= tempLength) {
- next = source.length();
- }else{
- next = source.indexOf(pattern.substring(patternOffset, tempLength),
- sourceOffset);
- }
-
- if (next < 0) {
- pos.errorIndex = sourceOffset;
- return null; // leave index as is to signal error
- } else {
- String strValue= source.substring(sourceOffset,next);
- if (!strValue.equals("{"+argumentNumbers[i]+"}"))
- resultArray[argumentNumbers[i]]
- = source.substring(sourceOffset,next);
- sourceOffset = next;
- }
- } else {
- tempStatus.index = sourceOffset;
- resultArray[argumentNumbers[i]]
- = formats[i].parseObject(source,tempStatus);
- if (tempStatus.index == sourceOffset) {
- pos.errorIndex = sourceOffset;
- return null; // leave index as is to signal error
- }
- sourceOffset = tempStatus.index; // update
- }
- }
- int len = pattern.length() - patternOffset;
- if (len == 0 || pattern.regionMatches(patternOffset,
- source, sourceOffset, len)) {
- pos.index = sourceOffset + len;
- } else {
- pos.errorIndex = sourceOffset;
- return null; // leave index as is to signal error
- }
- return resultArray;
- }
-
- public Object[] parse(String source) throws ParseException {
- ParsePosition pos = new ParsePosition(0);
- Object[] result = parse(source, pos);
- if (pos.index == 0) // unchanged, returned object is null
- throw new ParseException("MessageFormat parse error!", pos.errorIndex);
-
- return result;
- }
-
- public Object parseObject(String source, ParsePosition pos) {
- return parse(source, pos);
- }
-
- public Object clone() {
- MessageFormat other = (MessageFormat) super.clone();
-
- // clone arrays. Can't do with utility because of bug in Cloneable
- other.formats = formats.clone(); // shallow clone
- for (int i = 0; i < formats.length; ++i) {
- if (formats[i] != null)
- other.formats[i] = (Format)formats[i].clone();
- }
- // for primitives or immutables, shallow clone is enough
- other.offsets = offsets.clone();
- other.argumentNumbers = argumentNumbers.clone();
- return other;
- }
- public boolean equals(Object obj) {
- if (this == obj) // quick check
- return true;
- if (obj == null || getClass() != obj.getClass())
- return false;
- MessageFormat other = (MessageFormat) obj;
- return (maxOffset == other.maxOffset
- && pattern.equals(other.pattern)
- && ((locale != null && locale.equals(other.locale))
- || (locale == null && other.locale == null))
- && Arrays.equals(offsets,other.offsets)
- && Arrays.equals(argumentNumbers,other.argumentNumbers)
- && Arrays.equals(formats,other.formats));
- }
- public static class Field extends Format.Field {
- // Proclaim serial compatibility with 1.4 FCS
- private static final long serialVersionUID = 7899943957617360810L;
- protected Field(String name) {
- super(name);
- }
- protected Object readResolve() throws InvalidObjectException {
- if (this.getClass() != MessageFormat.Field.class) {
- throw new InvalidObjectException("subclass didn't correctly implement readResolve");
- }
- return ARGUMENT;
- }
- //
- // The constants
- //
- public final static Field ARGUMENT =
- new Field("message argument field");
- }
- }
为什么要使用静态内部类
- class Company {
-
- private String theCEO = "stupid";
- private static String companyName = "STUPID COM";
-
- // 1
- static class Employee {
- public Employee() {
- System.out.println("company name - " + companyName);
- // 2
- //System.out.println("CEO - " + theCEO);
- }
- }
-
- public Company(){
- System.out.println("Company object is created");
- }
- }
-
- public class Main {
-
- public static void main(String[] args) {
- // Company company = new Company();
- // Company.Employee employee = company.new Employee();
-
- // 3
- Company.Employee employee = new Company.Employee();
- }
- }
如果内部类不是静态的。要用这个内部类就必须先初始化包裹类。也是,如果不初始化出来对应的包裹类,内部类对象怎么能访问这些包裹类对象的非静态实例对象呢。
static
,员工类变成静态内部类。new Company.Employee()
。一般来说,内部类不需要访问包裹类的非静态成员的时候。或者只是做一个工具给外部调用,而这些工具需要按照功能区分为的时候使用静态内部类。
FormatElement:
{ ArgumentIndex }
{ ArgumentIndex , FormatType }
{ ArgumentIndex , FormatType , FormatStyle }
FormatType:
number
date
time
choice(需要使用ChoiceFormat)
FormatStyle:
short
medium
long
full
integer
currency
percent
SubformatPattern(子模式)
{0}、{1,number,short}、{2,number,#.#}属于FormatElement,0,1,2是ArgumentIndex
{1,number,short}里面的number属于FormatType,short则属于FormatStyle
{1,number,#.#}里面的#.#就属于子格式模式
-
- import java.text.MessageFormat;
-
- String str = "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}";
- Object[] array = new Object[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q"};
- String value = MessageFormat.format(str, array);
- System.out.println(value); // ABCDEFGHIJKLMNOPQ
-
-
- String message = "oh, {0} is a person";
- Object[] array = new Object[]{"ZhangSan"};
- String value = MessageFormat.format(message, array);
- System.out.println(value); // oh, ZhangSan is a person
-
-
- String message = "oh, {0,number,#.#} is a number";
- Object[] array = new Object[]{new Double(3.1415)};
- String value = MessageFormat.format(message, array);
- System.out.println(value); // oh, 3.1 is a number
-
-
- // MessageFormat的format方法源码
- public static String format(String pattern, Object ... arguments)
- {
- MessageFormat temp = new MessageFormat(pattern);
- return temp.format(arguments);
- }
对字符串的匹配比较智能
- String str = "{0} | {1} | {0} | {1}";
- Object[] array = new Object[] { "A", "B" };
- String value = MessageFormat.format(str, array);
- System.out.println(value); // A | B | A | B
- StringBuilder sb=new StringBuilder();
- sb.append(" insert into test_tb (");
- sb.append(" createTime, ");
- sb.append(" datefrom, ");
- sb.append(" dateto, ");
- sb.append(" name, ");
- sb.append(" intranetid, ");
- sb.append(" actualhour, ");
- sb.append(" planhour, ");
- sb.append(" status");
- sb.append(" ) values (");
- sb.append(" ''{0}'',");
- sb.append(" ''{1}'',");
- sb.append(" ''{2}'',");
- sb.append(" ''{3}'',");
- sb.append(" ''{4}'',");
- sb.append(" ''{5}'',");
- sb.append(" ''{6}'',");
- sb.append(" ''{7}''");
- sb.append(" )");
- String result=sb.toString();
-
- Object[] arr={createTime,datefrom,dateto,name,intranetid,actualhour,planhour,status};
- String sql=MessageFormat.format(result, arr);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。