java.text.Format及相关类详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java.text.Format及相关类详解相关的知识,希望对你有一定的参考价值。
java.text.Format
Format是一个用于格式化语言环境敏感的信息(如日期、消息和数字)的抽象基类,直接已知子类有DateFormat, MessageFormat, NumberFormat。
Format定义了编程接口,用于将语言环境敏感的对象格式化为String(使用format方法)和将String重新解析为对象(使用 parseObject方法)。
通常,一个Format的parseObject方法必须能解析任何由其Format方法格式化的字符串。不过,也可能存在不能解析的异常情况。例如,Format方法可能创建中间无分隔符的两个相邻整数,在这种情况下,parseObject无法判断哪个数字属于哪个数。
通常,一个Format的parseObject方法必须能解析任何由其Format方法格式化的字符串。不过,也可能存在不能解析的异常情况。例如,Format方法可能创建中间无分隔符的两个相邻整数,在这种情况下,parseObject无法判断哪个数字属于哪个数。
Java平台为格式化日期、消息和数字分别提供了三个特殊的Format的子类:DateFormat、MessageFormat和NumberFormat。具体的子类必须实现三个方法:
format(Object obj, StringBuffer toAppendTo, FieldPosition pos)
formatToCharacterIterator(Object obj)
parseObject(String source, ParsePosition pos)
这些常规方法允许对对象进行多态解析和格式化,还可以被使用(如被 MessageFormat 使用)。子类通常也为特定的输入类型提供了另外的format方法,也为特定的结果类型提供了parse方法。当在输入文本的开始没有任何所需格式的文本时,则任何不带 ParsePosition参数的parse方法都应该抛出ParseException。
大多数子类还将实现以下工厂方法:
getInstance 获取一个适合于当前语言环境的有用的格式对象
getInstance(Locale) 获取一个适合于指定语言环境的有用的格式对象。
此外,某些子类还可能为了更特殊的控制实现其它getXxxxInstance方法。例如,NumberFormat类提供了getPercentInstance和 getCurrencyInstance方法来获取特殊的数字格式器。
Format的子类如果允许程序员能为不同语言环境(比如用getInstance(Locale) )创建对象,必须实现以下类方法:
public static Locale[] getAvailableLocales()
最后子类定义一个常量集合来标识格式输出中的不同字段。这些常量用于创建一个FieldPosition对象该对象标识字段中所包含的信息及其在格式化结果中的位置。这些常量应当命名为item_FIELD,其中item标识了该字段。有关这些常量的例子,请参阅 ERA_FIELD及其在DateFormat中的同类。
format(Object obj, StringBuffer toAppendTo, FieldPosition pos)
formatToCharacterIterator(Object obj)
parseObject(String source, ParsePosition pos)
这些常规方法允许对对象进行多态解析和格式化,还可以被使用(如被 MessageFormat 使用)。子类通常也为特定的输入类型提供了另外的format方法,也为特定的结果类型提供了parse方法。当在输入文本的开始没有任何所需格式的文本时,则任何不带 ParsePosition参数的parse方法都应该抛出ParseException。
大多数子类还将实现以下工厂方法:
getInstance 获取一个适合于当前语言环境的有用的格式对象
getInstance(Locale) 获取一个适合于指定语言环境的有用的格式对象。
此外,某些子类还可能为了更特殊的控制实现其它getXxxxInstance方法。例如,NumberFormat类提供了getPercentInstance和 getCurrencyInstance方法来获取特殊的数字格式器。
Format的子类如果允许程序员能为不同语言环境(比如用getInstance(Locale) )创建对象,必须实现以下类方法:
public static Locale[] getAvailableLocales()
最后子类定义一个常量集合来标识格式输出中的不同字段。这些常量用于创建一个FieldPosition对象该对象标识字段中所包含的信息及其在格式化结果中的位置。这些常量应当命名为item_FIELD,其中item标识了该字段。有关这些常量的例子,请参阅 ERA_FIELD及其在DateFormat中的同类。
格式通常不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,其它必须保持外部同步。
java.text.FieldPosition
构造方法
public FieldPosition(int field)
为给定字段创建一个FieldPosition对象。字段由常量标识,在不同的Format子类中,常量名称一般以_FIELD结尾。
public FieldPosition(Format.Field attribute)
为给定的字段常量创建一个FieldPosition对象。字段由不同Format子类中定义的常量来标识。这等效于调用new FieldPosition(attribute, -1)。
public FieldPosition(Format.Field attribute,int fieldID)
为给定的字段创建一个FieldPosition对象。字段由来自Field的子类之一的属性常量以及一个由Format的子类定义的整型字段ID标识。
当attribute不为null时,需要使用Field的Format子类应当优先考虑attribute而忽略fieldID。
不过,旧的Format子类可能不知道Field而依靠fieldID。如果该字段没有相应的整型常量,则fieldID应为-1。
FieldPosition是Format及其子类用于在格式输出中(format(Object obj, StringBuffer toAppendTo, FieldPosition pos))标识字段的简单类。
FieldPosition保持对格式输出中字段位置的两个索引进行跟踪:字段的第一个字符的索引和紧跟字段的最后一个字符的索引。
不同的Format类中的format方法需要一个FieldPosition对象作为参数。使用此format方法执行部分格式化或者以获取格式化输出的信息(比如字段位置)。字段可以通过两种方式标识,两者的作用是一致的,只是Format.Field常量更详细,建议使用这种方式:
1、通过一个其名称通常以_FIELD结尾的整型常量。这些常量在Format的不同子类中定义:
FieldPosition保持对格式输出中字段位置的两个索引进行跟踪:字段的第一个字符的索引和紧跟字段的最后一个字符的索引。
不同的Format类中的format方法需要一个FieldPosition对象作为参数。使用此format方法执行部分格式化或者以获取格式化输出的信息(比如字段位置)。字段可以通过两种方式标识,两者的作用是一致的,只是Format.Field常量更详细,建议使用这种方式:
1、通过一个其名称通常以_FIELD结尾的整型常量。这些常量在Format的不同子类中定义:
NumberFormat
static int FRACTION_FIELD 用于构造FieldPosition对象的字段常量。 static int INTEGER_FIELD 用于构造FieldPosition对象的字段常量。
例子:
public static void main(String[] args) { NumberFormat numberFormat = NumberFormat.getInstance(); StringBuffer stringBuffer1 = new StringBuffer(); FieldPosition fieldPosition = new FieldPosition(NumberFormat.INTEGER_FIELD); BigDecimal bigDecimal = new BigDecimal("1.23456789"); stringBuffer1 = numberFormat.format(bigDecimal, stringBuffer1, fieldPosition); System.out.println("stringBuffer1 = " + stringBuffer1); System.out.println("INTEGER:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex()); fieldPosition = new FieldPosition(NumberFormat.FRACTION_FIELD); StringBuffer stringBuffer2 = new StringBuffer(); stringBuffer2 = numberFormat.format(bigDecimal, stringBuffer2, fieldPosition); System.out.println("stringBuffer2 = " + stringBuffer2); System.out.println("FRACTION:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex()); }
stringBuffer1 = 1.235 INTEGER:beginIndex=0,endIndex=1 stringBuffer2 = 1.235 FRACTION:beginIndex=2,endIndex=5
2、通过一个Format.Field常量:
NumberFormat.Field
static NumberFormat.Field CURRENCY 标识货币字段的常量。 static NumberFormat.Field DECIMAL_SEPARATOR 标识小数点字段的常量。 static NumberFormat.Field EXPONENT 标识指数字段的常量。 static NumberFormat.Field EXPONENT_SIGN 标识指数符号 (exponent sign) 字段的常量。 static NumberFormat.Field EXPONENT_SYMBOL 标识指数符号 (exponent symbol) 字段的常量。 static NumberFormat.Field FRACTION 标识小数字段的常量。 static NumberFormat.Field GROUPING_SEPARATOR 标识组分隔符字段的常量。 static NumberFormat.Field INTEGER 标识整数字段的常量。 static NumberFormat.Field PERCENT 标识百分数字段的常量。 static NumberFormat.Field PERMILLE 标识千分数字段的常量。 static NumberFormat.Field SIGN 标识符号字段的常量。
public static void main(String[] args) { NumberFormat numberFormat = NumberFormat.getInstance(); StringBuffer stringBuffer1 = new StringBuffer(); FieldPosition fieldPosition = new FieldPosition(NumberFormat.Field.INTEGER); BigDecimal bigDecimal = new BigDecimal("1.23456789"); stringBuffer1 = numberFormat.format(bigDecimal, stringBuffer1, fieldPosition); System.out.println("stringBuffer1 = " + stringBuffer1); System.out.println("INTEGER:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex()); fieldPosition = new FieldPosition(NumberFormat.Field.FRACTION); StringBuffer stringBuffer2 = new StringBuffer(); stringBuffer2 = numberFormat.format(bigDecimal, stringBuffer2, fieldPosition); System.out.println("stringBuffer2 = " + stringBuffer2); System.out.println("FRACTION:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex()); }
stringBuffer1 = 1.235 INTEGER:beginIndex=0,endIndex=1 stringBuffer2 = 1.235 FRACTION:beginIndex=2,endIndex=5
public static void main(String[] args) { DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); StringBuffer stringBuffer = new StringBuffer(); FieldPosition pos = new FieldPosition(DateFormat.Field.DAY_OF_MONTH); stringBuffer = dateFormat.format(new Date(), stringBuffer, pos); System.out.println("stringBuffer = " + stringBuffer); System.out.println("DATE_FIELD:beginIndex= " + pos.getBeginIndex() + ",endIndex=" + pos.getEndIndex()); }
stringBuffer = 2016年6月28日 上午11时07分18秒 DATE_FIELD:beginIndex= 7,endIndex=9
java.text.ParsePosition
ParsePosition是Format及其子类所使用的简单类,用来在解析过程中跟踪当前位置。各种Format类中的parseObject方法要求将 ParsePosition对象作为一个变量。解析具有不同格式的字符串时,可以使用同一个ParsePosition,因为索引参数记录的是当前位置。ParsePosition也会记录解析错误的位置。构造方法
public ParsePosition(int index)
创建一个具有给定初始索引的新 ParsePosition。
例子:
public static void main(String[] args) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String strings[] = {"xxx 2016-06-28 xxx1", "20160628 xxx2"}; for (int i = 0; i < strings.length; i++) { ParsePosition parsePosition = new ParsePosition(4);//从第四位开始处理 Date date = simpleDateFormat.parse(strings[i], parsePosition); //解析错误,返回null if (date == null) { System.out.println("无效日期:" + strings[i]); System.out.println("解析出错的索引=" + parsePosition.getErrorIndex()); System.out.println("当前索引=" + parsePosition.getIndex()); continue; } String substring = strings[i].substring(parsePosition.getIndex()); System.out.println("日期=" + date + ",剩余部分:" + substring); } }
日期=Tue Jun 28 00:00:00 CST 2016,剩余部分: xxx1 无效日期:20160628 xxx2 解析出错的索引=8 当前索引=4
java.text.NumberFormat
NumberFormat 是所有数值格式的抽象基类。此类提供格式化和解析数值的接口。NumberFormat 还提供了一些方法来确定哪些语言环境具有数值格式,以及它们的名称是什么。NumberFormat 可用于格式化和解析任何语言环境的数值。使代码能够完全独立于小数点、千位分隔符甚至所用特定小数位数的语言环境约定,并与数值格式是否为偶小数无关。
如何获得一个实例?
NumberFormat总共有三种实例,常规数值、货币数值,百分比数值,每种都可以用默认语言环境和指定语言环境。
常规数值:getInstance()(同getNumberInstance())、getInstance(Locale inLocale)(同getNumberInstance(Locale inLocale))
货币数值:getCurrencyInstance()、getCurrencyInstance(Locale inLocale)
百分比数值:getPercentInstance()、getPercentInstance(Locale inLocale)
public static Locale[] getAvailableLocales()
返回一个当前所支持的语言环境数组
void setCurrency(Currency currency)
设置格式化货币值时此数值格式使用的货币。
设置格式化货币值时此数值格式使用的货币。
void setGroupingUsed(boolean newValue)
设置此格式中是否使用分组,即是否有千位分隔符(逗号)。
void setMaximumFractionDigits(int newValue)
设置数的小数部分所允许的最大位数。与解析无关。
设置数的小数部分所允许的最大位数。与解析无关。
void setMaximumIntegerDigits(int newValue)
设置数的整数部分所允许的最大位数。与解析无关。
void setMinimumFractionDigits(int newValue)
设置数的小数部分所允许的最小位数。与解析无关。
void setMinimumIntegerDigits(int newValue)
设置数的整数部分所允许的最小位数。与解析无关。
void setParseIntegerOnly(boolean value)
设置数是否应该仅作为整数进行解析。与格式化无关。
例子:
public static void main(String[] args) throws Exception { //常规数值 NumberFormat format1 = NumberFormat.getNumberInstance(); System.out.println(format1.getMaximumIntegerDigits());//2147483647 System.out.println(format1.getMinimumIntegerDigits());//1 System.out.println(format1.getMaximumFractionDigits());//3 System.out.println(format1.getMinimumFractionDigits());//0 System.out.println(format1.isGroupingUsed());//true System.out.println(format1.isParseIntegerOnly());//false System.out.println(format1.format(10000000));//10,000,000 默认分组 System.out.println(format1.format(10000000.000));//10,000,000 小数点后全身0,被舍弃 System.out.println(format1.format(10000000.001));//10,000,000.001 System.out.println(format1.format(10000000.0001));//10,000,000 默认最大小数位数是3位 System.out.println(format1.parse("10000000.001"));//1.0000000001E7 默认可以解析小数 format1.setParseIntegerOnly(true); System.out.println(format1.parse("10000000.001"));//10000000 //百分比数值 NumberFormat format2 = NumberFormat.getPercentInstance(); System.out.println(format2.getMaximumIntegerDigits());//2147483647 System.out.println(format2.getMinimumIntegerDigits());//1 System.out.println(format2.getMaximumFractionDigits());//0 System.out.println(format2.getMinimumFractionDigits());//0 System.out.println(format2.isGroupingUsed());//true System.out.println(format2.isParseIntegerOnly());//false System.out.println(format2.format(1.01));//101% System.out.println(format2.format(1.001));//100% 默认最大小数位数是0 format2.setMaximumFractionDigits(1); System.out.println(format2.format(1.001));//100.1% System.out.println(format2.parse("100.1%"));// 1.001 默认可以解析小数 //货币格式 NumberFormat format3 = NumberFormat.getCurrencyInstance(); System.out.println(format3.getMaximumIntegerDigits());//2147483647 System.out.println(format3.getMinimumIntegerDigits());//1 System.out.println(format3.getMaximumFractionDigits());//2 System.out.println(format3.getMinimumFractionDigits());//2 System.out.println(format3.isGroupingUsed());//true System.out.println(format3.isParseIntegerOnly());//false System.out.println(format3.format(10000));//¥10,000.00 默认语言环境是zh_CN System.out.println(format3.parse("¥10,000.00"));//10000 }
java.text.DecimalFormat
DecimalFormat是NumberFormat的一个具体子类,用于格式化十进制数字。该类设计有各种功能,使其能够解析和格式化任意语言环境中的数,包括对西方语言、阿拉伯语和印度语数字的支持。通常不直接调用DecimalFormat的构造方法,要获取具体语言环境的DecimalFormat(包括默认语言环境),可调用NumberFormat的某个工厂方法,如getInstance()。如果看源码会发现getInstance()其实返回的就是DecimalFormat实例,因为以后的版本NumberFormat的工厂方法可能返回不同于DecimalFormat的子类:
NumberFormat f = NumberFormat.getInstance(loc); if (f instanceof DecimalFormat) { ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true); }DecimalFormat包含一个模式和一组符号。可直接使用applyPattern()或间接使用API方法来设置模式。符号存储在DecimalFormatSymbols象中。如果想要改变符号,比如小数点,可以使用和DecimalFormate关联的DecimalFormatSymbols,此类表示了DecimalFormat格式化数字所需的符号集(如小数点、组分隔符等等)。DecimalFormat 根据其语言环境数据为其自身创建一个DecimalFormatSymbols实例。如果需要更改这些符号,可从DecimalFormat#getDecimalFormatSymbols()获得DecimalFormatSymbols对象并修改它。通常程序员不需要修改DecimalFormatSymbols。
特殊符号
0 | 数字。阿拉伯数字,如果当前位置不存在数字,则显示为0 |
# | 数字。阿拉伯数字,在不影响数值的情况下,当前位置如果为0或者不存在,则不显示 |
. | 数字。小数分隔符或货币小数分隔符 |
- | 数字。减号 |
, | 数字。分组分隔符 |
E | 数字。分隔科学计数法中的尾数和指数。在前缀或后缀中无需加引号 |
; | 子模式边界。分隔正数和负数子模式 |
% | 前缀或后缀。乘以 100 并显示为百分数 |
\u2030 | 前缀或后缀。乘以 1000 并显示为千分数 |
¤(\u00A4) | 前缀或后缀。货币记号,由货币符号替换。如果两个同时出现,则用国际货币符号替换。如果出现在某个模式中,则使用货币小数分隔符,而不使用小数分隔符 |
‘ | 前缀或后缀。用于在前缀或或后缀中为特殊字符加引号,例如 "‘#‘#" 将 123 格式化为 "#123"。要创建单引号本身,请连续使用两个单引号:"# o‘‘clock" |
语法
1、前缀和后缀:数字前后的符号,除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符。
2、小数分隔符和千位分隔符应该是不同的字符,否则将不可能进行解析。
3、如果使用具有多个分组字符的模式,则最后一个分隔符和整数结尾之间的间隔才是使用的分组大小。所以 "#,##,###,####" == "######,####" == "##,####,####"。
构造方法
DecimalFormat()
使用默认模式和默认语言环境的符号创建一个DecimalFormat。
DecimalFormat(String pattern)
使用给定的模式和默认语言环境的符号创建一个DecimalFormat。
DecimalFormat(String pattern, DecimalFormatSymbols symbols)
使用给定的模式和符号创建一个DecimalFormat。
使用默认模式和默认语言环境的符号创建一个DecimalFormat。
DecimalFormat(String pattern)
使用给定的模式和默认语言环境的符号创建一个DecimalFormat。
DecimalFormat(String pattern, DecimalFormatSymbols symbols)
使用给定的模式和符号创建一个DecimalFormat。
例子:
public static void main(String[] args) throws Exception { DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(); unusualSymbols.setDecimalSeparator(‘|‘); unusualSymbols.setGroupingSeparator(‘^‘); String strange = "#,##0.###"; DecimalFormat weirdFormatter = new DecimalFormat(strange, unusualSymbols); weirdFormatter.setGroupingSize(4); String bizarre = weirdFormatter.format(12345.678); System.out.println(bizarre);//1^2345|678 }
以上是关于java.text.Format及相关类详解的主要内容,如果未能解决你的问题,请参考以下文章
SimpleDateFormat 的 format 方法使用具体解释
SPRING05_BeanFactory概述HierarchicalBeanFactoryListableBeanFacotoryDefaultListableBeanFactory档案馆详解(代码片