首页 > 编程语言 >java的NumberFormat、DecimalFormat、MessageFormat类源码详解

java的NumberFormat、DecimalFormat、MessageFormat类源码详解

时间:2023-02-23 22:33:02浏览次数:46  
标签:return NumberFormat format number 源码 java public append


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;
}
}

java的NumberFormat、DecimalFormat、MessageFormat类源码详解_ide

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();
}
}

如果内部类不是静态的。要用这个内部类就必须先初始化包裹类。也是,如果不初始化出来对应的包裹类,内部类对象怎么能访问这些包裹类对象的非静态实例对象呢。

  1. 加​​static​​,员工类变成静态内部类。
  2. 静态内部类不能再访问包裹类的非静态成员。
  3. 看起来正常的初始化方法:​​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);

 

标签:return,NumberFormat,format,number,源码,java,public,append
From: https://blog.51cto.com/u_11837698/6081997

相关文章

  • Jenkins 添加节点 java web方式
    启用代理端口可以自己指定添加节点参数说明:Name(名称):即节点名称Description(描述):介绍该节点的作用,如Docker构建ofexecutors(并发构建数):定义该节点可以执行多少......
  • 深入学习jquery源码之each()
    $.each()遍历一个数组或对象,可以是DOM、json等格式,等价于for循环返回值:jQuery.each(callback) 参数:对于每个匹配的元素所要执行的函数概述:以每一个匹配的元素作为上下文......
  • 深入学习jquery源码之trigger()与triggerHandler()
    深入学习jquery源码之trigger()与triggerHandler()trigger(type,[data])概述:在每一个匹配的元素上触发某类事件。这个函数也会导致浏览器同名的默认行为的执行。比如,如果用......
  • 深入学习jquery源码之map()
    概述将一组元素转换成其他数组(不论是否是元素数组)你可以用这个函数来建立一个列表,不论是值、属性还是CSS样式,或者其他特别形式。这都可以用'$.map()'来方便的建立。参数call......
  • 深入学习jquery源码之插件机制(二)
    高级插件概念链接提供对默认插件设置的公共访问我们可以而且应该对上面的代码做出的改进并公开默认的插件设置。这很重要,因为它使插件用户很容易用最少的代码覆盖/自定义......
  • 深入学习jquery源码之jQuery的二次开发
    深入学习jquery源码之jQuery的二次开发jquery.js的设计与实现(function(global,factory){if(typeofmodule==="object"&&typeofmodule.exports==="object")......
  • 深入学习jquery源码之merge()和unique()
    深入学习jquery源码之merge()概述:合并两个数组到第一个数组上。返回的结果会修改第一个数组的内容——第一个数组的元素后面跟着第二个数组的元素。要去除重复项,请使用$.uni......
  • 深入学习jquery源码之show()和hide()
    jQueryshow([speed,[easing],[fn]])概述:显示隐藏的匹配元素。这个就是'show(speed,[callback])'无动画的版本。如果选择的元素是可见的,这个方法将不会改变任何东西。......
  • 深入学习jquery源码之继承框架的实现
    深入学习jquery源码之继承框架的实现继承框架的实现实现自己的extend方法/*SimpleJavaScriptInheritance*ByJohnResighttp://ejohn.org/*MITLicensed.*///Insp......
  • 深入学习jquery源码之创建科学、复用率高的对象
    常规创建对象的方式通过{},[]来定义数组和对象1.{}大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数。2.[]中括号,表示一个数组,也可以理解为一个数组对象......