The java NumberFormat, DecimalFormat, MessageFormat source category Explanation
The definition of the class 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));
Display: 1234.560
2. NF = NumberFormat.getPercentInstance the NumberFormat ();
// nf.setMinimumFractionDigits (2); retained after several decimal display: 47.00%
System.out.println (nf.format (0.47));
Show: 47%
(Act II)
DecimalFormat df1 = new DecimalFormat ( "## 00%."); //##.00% percentage format, with the latter is less than 2 0 filled
baifenbi = df1.format (fen);
Display: 47.00%
3。DecimalFormat df = new DecimalFormat("###,##0.00");
System.out.println(nf.format(24.7));
Display: 24.70
System.out.println(nf.format(23123.47));
Display: 123,23.47
Added: 0.00,0.01; 0.00%, 0.12% of such data, according to the above format may result in data displayed as: .00, .01; .00% ,. 12%, how to do it? As long as the format changed:
DecimalFormat df1 = new DecimalFormat("0.00");
DecimalFormat df2 = new DecimalFormat("0.00%");
df1.formatI(number);df2.formatI(number);
Display: 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));
}
}
Results:
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");
}
}
Why use a static inner classes
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();
}
}
If the internal class is not static. Use this inner class must be initialized parcel. Also, if it does not initialize the corresponding parcel, the internal class object how to access these parcels of non-static class object instance of the object it.
- Plus
static
, the staff became like static inner classes. - Static inner classes can not access non-static member wrapped class.
- It looks normal initialization method:
new Company.Employee()
.
In general, inner classes do not need to access non-static member class inclusions of the time. Or just a tool to make external calls, and these tools need to be divided into zones according to function when using static inner classes.
FormatElement:
{ ArgumentIndex }
{ ArgumentIndex , FormatType }
{ ArgumentIndex , FormatType , FormatStyle }
FormatType:
Number
DATE
Time
Choice (required A ChoiceFormat)
FormatStyle:
Short
Medium
Long
Full
Integer
Currency
Percent
SubformatPattern (child mode)
{0}, {1, number, short}, {2, number, #. #} Belong FormatElement, 0,1,2 is ArgumentIndex
{1, number, short} which belong to the number FormatType, short belong FormatStyle
{1, number, #. #} # Inside. Belongs to the sub-format mode #
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);
}
Matching string of intelligence
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);