首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >7. JDK拍了拍你:字符串拼接一定记得用MessageFormat#format

7. JDK拍了拍你:字符串拼接一定记得用MessageFormat#format

作者头像
YourBatman
发布于 2022-03-08 07:07:19
发布于 2022-03-08 07:07:19
1.6K00
代码可运行
举报
文章被收录于专栏:BAT的乌托邦BAT的乌托邦
运行总次数:0
代码可运行

目录

✍前言

你好,我是A哥(YourBatman)。本文所属专栏:Spring类型转换,公号后台回复专栏名即可获取全部内容。

在日常开发中,我们经常会有格式化的需求,如日期格式化、数字格式化、钱币格式化等等。

格式化器的作用似乎跟转换器的作用类似,但是它们的关注点却不一样:

  • 转换器:将类型S转换为类型T,关注的是类型而非格式
  • 格式化器: String <-> Java类型。这么一看它似乎和PropertyEditor类似,但是它的关注点是字符串的格式

Spring有自己的格式化器抽象org.springframework.format.Formatter,但是谈到格式化器,必然就会联想起来JDK自己的java.text.Format体系。为后文做好铺垫,本文就先介绍下JDK为我们提供了哪些格式化能力。

版本约定

  • JDK:8

✍正文

Java里从来都缺少不了字符串拼接的活,JDK也提供了多种“工具”供我们使用,如:StringBuffer、StringBuilder以及最直接的+号,相信这些大家都有用过。但这都不是本文的内容,本文将讲解格式化器,给你提供一个新的思路来拼接字符串,并且是推荐方案。

JDK内置有格式化器,便是java.text.Format体系。它是个抽象类,提供了两个抽象方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public abstract class Format implements Serializable, Cloneable {
    public abstract StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos);	
	public abstract Object parseObject (String source, ParsePosition pos);
}
  • format:将Object格式化为String,并将此String放到toAppendTo里面
  • parseObject:讲String转换为Object,是format方法的逆向操作

Java SE针对于Format抽象类对于常见的应用场景分别提供了三个子类实现:

DateFormat:日期时间格式化

抽象类。用于用于格式化日期/时间类型java.util.Date。虽然是抽象类,但它提供了几个静态方法用于获取它的实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 格式化日期 + 时间
public final static DateFormat getInstance() {
    return getDateTimeInstance(SHORT, SHORT);
}
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale){
    return get(timeStyle, dateStyle, 3, aLocale);
}

// 格式化日期
public final static DateFormat getDateInstance(int style, Locale aLocale) {
    return get(0, style, 2, aLocale);
}
// 格式化时间
public final static DateFormat getTimeInstance(int style, Locale aLocale){
    return get(style, 0, 1, aLocale);
}

有了这些静态方法,你可在不必关心具体实现的情况下直接使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * {@link DateFormat}
 */
@Test
public void test1() {
    Date curr = new Date();

    // 格式化日期 + 时间
    System.out.println(DateFormat.getInstance().getClass() + "-->" + DateFormat.getInstance().format(curr));
    System.out.println(DateFormat.getDateTimeInstance().getClass() + "-->" + DateFormat.getDateTimeInstance().format(curr));

    // 格式化日期
    System.out.println(DateFormat.getDateInstance().getClass() + "-->" + DateFormat.getDateInstance().format(curr));

    // 格式化时间
    System.out.println(DateFormat.getTimeInstance().getClass() + "-->" + DateFormat.getTimeInstance().format(curr));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class java.text.SimpleDateFormat-->20-12-25 上午7:19
class java.text.SimpleDateFormat-->2020-12-25 7:19:30
class java.text.SimpleDateFormat-->2020-12-25
class java.text.SimpleDateFormat-->7:19:30

嗯,可以看到底层实现其实是咱们熟悉的SimpleDateFormat。实话说,这种做法不常用,狠一点:基本不会用(框架开发者可能会用做兜底实现)。

SimpleDateFormat

一般来说,我们会直接使用SimpleDateFormat来对Date进行格式化,它可以自己指定Pattern,个性化十足。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test2() {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // yyyy-MM-dd HH:mm:ss
    System.out.println(dateFormat.format(new Date()));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2020-12-25

关于SimpleDateFormat的使用方式不再啰嗦,不会的就可走自行劝退手续了。此处只提醒一点:SimpleDateFormat线程不安全

说明:JDK 8以后不再建议使用Date类型,也就不会再使用到DateFormat。同时我个人建议:在项目中可强制严令禁用

NumberFormat:数字格式化

抽象类。用于格式化数字,它可以对数字进行任意格式化,如小数、百分数、十进制数等等。它有两个实现类:

类结构和DateFormat类似,也提供了getXXXInstance静态方法给你直接使用,无需关心底层实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test41() {
    double myNum = 1220.0455;

    System.out.println(NumberFormat.getInstance().getClass() + "-->" + NumberFormat.getInstance().format(myNum));
    System.out.println(NumberFormat.getCurrencyInstance().getClass() + "-->" + NumberFormat.getCurrencyInstance().format(myNum));
    System.out.println(NumberFormat.getIntegerInstance().getClass() + "-->" + NumberFormat.getIntegerInstance().format(myNum));
    System.out.println(NumberFormat.getNumberInstance().getClass() + "-->" + NumberFormat.getNumberInstance().format(myNum));
    System.out.println(NumberFormat.getPercentInstance().getClass() + "-->" + NumberFormat.getPercentInstance().format(myNum));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class java.text.DecimalFormat-->1,220.045
class java.text.DecimalFormat-->1,220.05
class java.text.DecimalFormat-->1,220
class java.text.DecimalFormat-->1,220.045
class java.text.DecimalFormat-->122,005%

这一看就知道DecimalFormat是NumberFormat的主力了。

DecimalFormat

Decimal:小数,小数的,十进位的。

用于格式化十进制数字。它具有各种特性,可以解析和格式化数字,包括:西方数字、阿拉伯数字和印度数字。它还支持不同种类的数字,包括:整数(123)、小数(123.4)、科学记数法(1.23E4)、百分数(12%)和货币金额($123)。所有这些都可以进行本地化。

下面是它的构造器:

其中最为重要的就是这个pattern(不带参数的构造器一般不会用),它表示格式化的模式/模版。一般来说我们对DateFormat的pattern比较熟悉,但对数字格式化的模版符号了解甚少。这里我就帮你整理出这个表格(信息源自JDK官网),记得搜藏哦:

符号

Localtion

是否本地化

释义

0

Number

Digit

#

Number

Digit。若是0就显示为空

.

Number

小数/货币分隔符

-

Number

就代表减号

,

Number

分组分隔符

E

Number

科学计数法分隔符(位数和指数)

%

前/后缀

乘以100并显示为百分数

¤

前/后缀

货币记号。若连续出现两次就用国际货币符号代替

'

前后缀

用于引用特殊字符。作用类似于转义字符

说明:Number和Digit的区别:

  • Number是个抽象概念,其表达形式可以是数字、手势、声音等等。如1024就是个number
  • Digit是用来表达的单独符号。如0-9这是个digit就可以用来表示number,如1024就是由1、0、2、4这四个digit组成的

看了这个表格的符号规则,估计很多同学还是一脸懵逼。不啰嗦了,上干货

一、0和#的使用(最常见使用场景)

这是最经典、最常见的使用场景,甚至来说你有可能职业生涯会用到此场景。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * {@link DecimalFormat}
 */
@Test
public void test4() {
    double myNum = 1220.0455;

    System.out.println("===============0的使用===============");
    System.out.println("只保留整数部分:" + new DecimalFormat("0").format(myNum));
    System.out.println("保留3位小数:" + new DecimalFormat("0.000").format(myNum));
    System.out.println("整数部分、小数部分都5位。不够的都用0补位(整数高位部,小数低位补):" + new DecimalFormat("00000.00000").format(myNum));

    System.out.println("===============#的使用===============");
    System.out.println("只保留整数部分:" + new DecimalFormat("#").format(myNum));
    System.out.println("保留2为小数并以百分比输出:" + new DecimalFormat("#.##%").format(myNum));

    // 非标准数字(不建议这么用)
    System.out.println("===============非标准数字的使用===============");
    System.out.println(new DecimalFormat("666").format(myNum));
    System.out.println(new DecimalFormat(".6666").format(myNum));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
===============0的使用===============
只保留整数部分:1220
保留3位小数:1220.045
整数部分、小数部分都5位。不够的都用0补位(整数高位部,小数低位补)01220.04550
===============#的使用===============
只保留整数部分:1220
保留2为小数并以百分比输出:122004.55%
===============非标准数字的使用===============
661220
1220.666

通过此案例,大致可得出如下结论:

  • 整数部分:
    • 0和#都可用于取出全部整数部分
    • 0的个数决定整数部分长度,不够高位补0;#则无此约束,N多个#是一样的效果
  • 小数部分:
    • 可保留小数点后N位(0和#效果一样)
    • 若小数点后位数不够,若使用的0那就低位补0,若使用#就不补(该是几位就是几位)
  • 数字(1-9):并不建议模版里直接写1-9这样的数字,了解下即可
二、科学计数法E

如果你不是在证券/银行行业,这个大概率是用不着的(即使在,你估计也不会用它)。来几个例子感受一把就成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test5() {
    double myNum = 1220.0455;

    System.out.println(new DecimalFormat("0E0").format(myNum));
    System.out.println(new DecimalFormat("0E00").format(myNum));
    System.out.println(new DecimalFormat("00000E00000").format(myNum));
    System.out.println(new DecimalFormat("#E0").format(myNum));
    System.out.println(new DecimalFormat("#E00").format(myNum));
    System.out.println(new DecimalFormat("#####E00000").format(myNum));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1E3
1E03
12200E-00001
.1E4
.1E04
1220E00000
三、分组分隔符,

分组分隔符比较常用,它就是我们常看到的逗号,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test6() {
    double myNum = 1220.0455;

    System.out.println(new DecimalFormat(",###").format(myNum));
    System.out.println(new DecimalFormat(",##").format(myNum));
    System.out.println(new DecimalFormat(",##").format(123456789));

    // 分隔符,左边是无效的
    System.out.println(new DecimalFormat("###,##").format(myNum));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1,220
12,20
1,23,45,67,89
12,20
四、百分号%

在展示层面也比较常用,用于把一个数字用%形式表示出来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test42() {
    double myNum = 1220.0455;

    System.out.println("百分位表示:" + new DecimalFormat("#.##%").format(myNum));
    System.out.println("千分位表示:" + new DecimalFormat("#.##\u2030").format(myNum));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
百分位表示:122004.55%
千分位表示:1220045.5
五、本地货币符号¤

嗯,这个符号¤,键盘竟无法直接输出,得使用软键盘(建议使用copy大法)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test7() {
    double myNum = 1220.0455;

    System.out.println(new DecimalFormat(",000.00¤").format(myNum));
    System.out.println(new DecimalFormat(",000.¤00").format(myNum));
    System.out.println(new DecimalFormat("¤,000.00").format(myNum));
    System.out.println(new DecimalFormat("¤,000.¤00").format(myNum));
    // 世界货币表达形式
    System.out.println(new DecimalFormat(",000.00¤¤").format(myNum));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1,220.051,220.05¥
¥1,220.05
1,220.05¥¥
¥1,220.051,220.05CNY

注意最后一条结果:如果连续出现两次,代表货币符号的国际代号。

说明:结果默认都做了Locale本地化处理的,若你在其它国家就不会再是¥人名币符号喽

DecimalFormat就先介绍到这了,其实掌握了它就基本等于掌握了NumberFormat。接下来再简要看看它另外一个“儿子”:ChoiceFormat。

ChoiceFormat

Choice:精选的,仔细推敲的。

这个格式化器非常有意思:相当于以数字为键,字符串为值的键值对。使用一组double类型的数组作为键,一组String类型的数组作为值,两数组相同(不一定必须是相同,见示例)索引值的元素作为一对。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test8() {
    double[] limits = {1, 2, 3, 4, 5, 6, 7};
    String[] formats = {"周一", "周二", "周三", "周四", "周五", "周六", "周天"};
    NumberFormat numberFormat = new ChoiceFormat(limits, formats);

    System.out.println(numberFormat.format(1));
    System.out.println(numberFormat.format(4.3));
    System.out.println(numberFormat.format(5.8));
    System.out.println(numberFormat.format(9.1));
    System.out.println(numberFormat.format(11));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
周一
周四
周五
周天
周天

结果解释:

  1. 4.3位于4和5之间,取值4;5.8位于5和6之间,取值5
  2. 9.1和11均超过了数组最大值(或者说找不到匹配的),则取值最后一对键值对

可能你会想这有什么使用场景???是的,不得不承认它的使用场景较少,本文下面会介绍下它和MessageFormat的一个使用场景。

如果说DateFormatNumberFormat都用没什么花样,主要记住它的pattern语法格式就成,那么就下来这个格式化器就是本文的主菜了,使用场景非常的广泛,它就是MessageFormat

MessageFormat:字符串格式化

MessageFormat提供了一种与语言无关(不管你在中国还是其它国家,效果一样)的方式生成拼接消息/拼接字符串的方法。使用它来构造显示给最终用户的消息。MessageFormat接受一组对象,对它们进行格式化,然后在模式的适当位置插入格式化的字符串。

先来个最简单的使用示例体验一把:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * {@link MessageFormat}
 */
@Test
public void test9() {
    String sourceStrPattern = "Hello {0},my name is {1}";
    Object[] args = new Object[]{"girl", "YourBatman"};

    String formatedStr = MessageFormat.format(sourceStrPattern, args);
    System.out.println(formatedStr);
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Hello girl,my name is YourBatman

有没有中似曾相似的感觉,是不是和String.format()的作用特别像?是的,它俩的用法区别,到底使用税文下也会讨论。

要熟悉MessageFormat的使用,主要是要熟悉它的参数模式(你也可以理解为pattern)。

参数模式

MessageFormat采用{}来标记需要被替换/插入的部分,其中{}里面的参数结构具有一定模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ArgumentIndex[,FormatType[,FormatStyle]] 
  • ArgumentIndex非必须。从0开始的索引值
  • FormatType非必须。使用不同的java.text.Format实现类对入参进行格式化处理。它能有如下值:
    • number:调用NumberFormat进行格式化
    • date:调用DateFormat进行格式化
    • time:调用DateFormat进行格式化
    • choice:调用ChoiceFormat进行格式化
  • FormatStyle非必须。设置FormatType使用的样式。它能有如下值:
    • short、medium、long、full、integer、currency、percent、SubformPattern(如日期格式、数字格式#.##等)

说明:FormatType和FormatStyle只有在传入值为日期时间、数字、百分比等类型时才有可能需要设置,使用得并不多。毕竟:我在外部格式化好后再放进去不香吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test10() {
    MessageFormat messageFormat = new MessageFormat("Hello, my name is {0}. I’am {1,number,#.##} years old. Today is {2,date,yyyy-MM-dd HH:mm:ss}");
    // 亦可通过编程式 显示指定某个位置要使用的格式化器
    // messageFormat.setFormatByArgumentIndex(1, new DecimalFormat("#.###"));

    System.out.println(messageFormat.format(new Object[]{"YourBatman", 24.123456, new Date()}));
}

运行程序,输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Hello, my name is YourBatman. I’am 24.12 years old. Today is 2020-12-26 15:24:28

它既可以直接在模版里指定格式化模式类型,也可以通过API方法set指定格式化器,当然你也可以再外部格式化好后再放进去,三种方式均可,任君选择。

注意事项

下面基于此示例,对MessageFormat的使用注意事项作出几点强调。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void test11() {
    System.out.println(MessageFormat.format("{1} - {1}", new Object[]{1})); // {1} - {1}
    System.out.println(MessageFormat.format("{0} - {1}", new Object[]{1})); // 输出:1 - {1}
    System.out.println(MessageFormat.format("{0} - {1}", new Object[]{1, 2, 3})); // 输出:1 - 2

    System.out.println("---------------------------------");

    System.out.println(MessageFormat.format("'{0} - {1}", new Object[]{1, 2})); // 输出:{0} - {1}
    System.out.println(MessageFormat.format("''{0} - {1}", new Object[]{1, 2})); // 输出:'1 - 2
    System.out.println(MessageFormat.format("'{0}' - {1}", new Object[]{1, 2})); // {0} - 2
    // 若你数据库值两边都需要''包起来,请你这么写
    System.out.println(MessageFormat.format("''{0}'' - {1}", new Object[]{1, 2})); // '1' - 2

    System.out.println("---------------------------------");
    System.out.println(MessageFormat.format("0} - {1}", new Object[]{1, 2})); // 0} - 2
    System.out.println(MessageFormat.format("{0 - {1}", new Object[]{1, 2})); // java.lang.IllegalArgumentException: Unmatched braces in the pattern.
}
  1. 参数模式的索引值必须从0开始,否则所有索引值无效
  2. 实际传入的参数个数可以和索引个数不匹配,不报错(能匹配上几个算几个)
  3. 两个单引号''才算作一个',若只写一个将被忽略甚至影响整个表达式
    1. 谨慎使用单引号'
    2. 关注'的匹配关系
  4. {}只写左边报错,只写右边正常输出(注意参数的对应关系)

static方法的性能问题

我们知道MessageFormat提供有一个static静态方法,非常方便的的使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static String format(String pattern, Object ... arguments) {
    MessageFormat temp = new MessageFormat(pattern);
    return temp.format(arguments);
}

可以清晰看到,该静态方法本质上还是构造了一个MessageFormat实例去做格式化的。因此:若你要多次(如高并发场景)格式化同一个模版(参数可不一样)的话,那么提前创建好一个全局的(非static) MessageFormat实例再执行格式化是最好的,而非一直调用其静态方法。

说明:若你的系统非高并发场景,此性能损耗基本无需考虑哈,怎么方便怎么来。毕竟朝生夕死的对象对JVM来说没啥压力

和String.format选谁?

二者都能用于字符串拼接(格式化)上,撇开MessageFormat支持各种模式不说,我们只需要考虑它俩的性能上差异。

  • MeesageFormat:先分析(模版可提前分析,且可以只分析一次),再在指定位置上插入相应的值
    • 分析:遍历字符串,维护一个{}数组并记录位置
    • 填值
  • String.format:该静态方法是采用运行时用正则表达式 匹配到占位符,然后执行替换的
    • 正则表达式为"%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"
    • 根据正则匹配到占位符列表和位置,然后填值

一说到正则表达式,我心里就发触,因为它对性能是不友好的,所以孰优孰劣,高下立判。

说明:还是那句话,没有绝对的谁好谁坏,如果你的系统对性能不敏感,那就是方便第一

经典使用场景

这个就很多啦,最常见的有:HTML拼接、SQL拼接、异常信息拼接等等。

比如下面这个SQL拼接:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
StringBuilder sb =new StringBuilder();
sb.append("insert into user (");
sb.append("		name,");
sb.append("		accountId,");
sb.append("		zhName,");
sb.append("		enname,");
sb.append("		status");
sb.append(") values (");
sb.append("		''{0}'',");
sb.append("		{1},");
sb.append("		''{2}'',");
sb.append("		''{3}'',");
sb.append("		{4},");
sb.append(")");

Object[] args = {name, accountId, zhName, enname, status};

// 最终SQL
String sql = MessageFormat.format(sb.toString(), arr);

你看,多工整。

说明:如果值是字符串需要'包起来,那么请使用两边各两个包起来

✍总结

本文内容介绍了JDK原生的格式化器知识点,主要作用在这三个方面:

  • DateFormat:日期时间格式化
  • NumberFormat:数字格式化
  • MessageFormat:字符串格式化

Spring是直接面向使用者的框架产品,很显然这些是不够用的,并且JDK的格式化器在设计上存在一些弊端。比如经常被吐槽的:日期/时间类型格式化器SimpleDateFormat为毛在java.text包里,而它格式化的类型Date却在java.util包内,这实为不合适。

有了JDK格式化器作为基础,下篇我们就可以浩浩荡荡的走进Spring格式化器的大门了,看看它是如何优于JDK进行设计和抽象的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring周边:国际化、Format
Locale 类代表一个特定的地理、语言和国家环境。Locale 向一些对国家和语言、地理等比较敏感的类提供国家地区语言信息,这些类有DateFormat、NumberFormat等等。
WEBJ2EE
2019/11/06
7960
Spring周边:国际化、Format
Java魔法堂:初探MessageFormat.format和ChoiceFormat
一、前言                                 刚开始从.net的转向java的时候总觉得 String.format 用得不习惯,希望格式模版会这样 {0}, this is {1}'s cat.{1},this is {0}'s dog. 而不是 %1$s,this is %2$s's cat.%2$s,this is %1$s's dog. 。后来发现 java.text.MessageFormat.format 可以满足我这个小小的愿望。 二、静态方法 java.text.
^_^肥仔John
2018/01/18
9050
2019-04-01 别再自己拼字符串了,Java中MessageFormat的使用
这是String类型的静态方法,但是除此之外,JDK提供了更好用的字符串替换方法,就是
Albert陈凯
2019/04/09
3.8K0
8. 格式化器大一统 -- Spring的Formatter抽象
上篇文章 介绍了java.text.Format格式化体系,作为JDK 1.0就提供的格式化器,除了设计上存在一定缺陷,过于底层无法标准化对使用者不够友好,这都是对格式化器提出的更高要求。Spring作为Java开发的标准基建,本文就来看看它做了哪些补充。
YourBatman
2022/03/08
1.1K0
8. 格式化器大一统 -- Spring的Formatter抽象
8. 格式化器大一统 -- Spring的Formatter抽象
上篇文章 介绍了java.text.Format格式化体系,作为JDK 1.0就提供的格式化器,除了设计上存在一定缺陷,过于底层无法标准化对使用者不够友好,这都是对格式化器提出的更高要求。Spring作为Java开发的标准基建,本文就来看看它做了哪些补充。
YourBatman
2021/01/11
1.2K0
8. 格式化器大一统 -- Spring的Formatter抽象
Java避坑指南: java.text.MessageFormat 对较大整数类型的格式化问题
使用org.apache.ibatis.jdbc.SQL动态生成sql时候,为了灵活设置参数,使用了MessageFormat来格式化:
崔认知
2023/06/19
4720
Java避坑指南: java.text.MessageFormat  对较大整数类型的格式化问题
【小家Spring】聊聊Spring中的格式化:Formatter、AnnotationFormatterFactory、DateFormatter以及@DateTimeFormat...
Converter只完成了数据类型的转换,却不负责输入输出数据的格式化工作,日期时间、货币等虽都以字符串形式存在,却有不同的格式。
YourBatman
2019/09/03
4.1K0
【小家Spring】聊聊Spring中的格式化:Formatter、AnnotationFormatterFactory、DateFormatter以及@DateTimeFormat...
Spring-国际化信息01-基础知识
假设我们开发一个支持多国语言的Web应用系统,要求能够根据客户端系统的语言类型返回对应的界面。
小小工匠
2021/08/16
6390
sqlformat数字格式化_java怎么输出数字
以前用到要对数字格式的地方,都是直接到网上搜一下。拿过来能用就行。因为平时用的不多。但是最近的项目对这个用的多了。网上拿来的不够用了。自己看了java源码把这方面恶补了。而且最近也好长时间没有写博客了。正好写一篇抛砖引玉吧。
全栈程序员站长
2022/11/07
1.8K0
字符串模板
StringTemplate4是一种基于java的模板引擎库;类似于velocity, FreeMarker. 可以用于生成源代码, web页面, 电子邮件等多种样式的文本. StringTemplate4拥有比其他模板引擎更加强大的功能.
一个架构师
2022/06/27
7960
java 常规类型消息的格式化 原
0.slf4j有一个common logger没有的功能,字符串中的{}会被替换,如下:
wuweixiang
2018/08/14
6180
java BigDecimal用法详解(保留小数,四舍五入,数字格式化,科学计数法转数字等)
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
全栈程序员站长
2022/09/05
12K0
java 日期格式化– SimpleDateFormat 的使用。字符串转日期,日期转字符串
日期和时间格式由 日期和时间模式字符串 指定。在 日期和时间模式字符串 中,未加引号的字母 ‘A’ 到 ‘Z’ 和 ‘a’ 到 ‘z’ 被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号 (‘) 引起来,以免进行解释。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串 白话文的讲:这些A——Z,a——z这些字母(不被单引号包围的)会被特殊处理替换为对应的日期时间,其他的字符串还是原样输出。
全栈程序员站长
2022/07/01
6.3K0
java 日期格式化– SimpleDateFormat 的使用。字符串转日期,日期转字符串
JavaWeb开发——软件国际化(动态元素国际化)
DateFormat 类可以将一个日期/时间对象格式化为表示某个国家地区的日期/时间字符串。
wangweijun
2020/02/14
1.1K0
刷题小问题合计——持续更新
对于大数据问题,如果暴力求解必定超时,不妨先写出一些(不)符合的数,尝试寻找规律。
matt
2022/10/25
8230
刷题小问题合计——持续更新
Spring官网阅读(十一)ApplicationContext详细介绍(上)
从上图中可以发现,ApplicationContext接口继承了很多接口,这些接口我们可以将其分为五类:
程序员DMZ
2020/07/06
1.5K0
Java 一步一步实现高逼格的字符串替换工具(一)
Java 一步一步实现高逼格的字符串替换工具(一) 如果你有一段模板, 需要用某些数据替换其中的关键信息,怎么做 "hello, {user}, welcome to {place}!" 通过传不同的user, 和 place 来输出不同的文案 ##1.一般做法 用String.replaceAll 来进行替换就好了, 无非是多调用几遍,代码写起来也简单,如下 @Test public void testReplace() { String text = "hello {user}, welc
一灰灰blog
2018/02/06
6.2K1
和小伙伴们仔细梳理一下 Spring 国际化吧!从用法到源码!
国际化(Internationalization,简称 I18N)是指在 Java 应用程序中实现国际化的技术和方法。Java 提供了一套强大的国际化支持,使开发人员能够编写适应不同语言、地区和文化的应用程序。
江南一点雨
2023/11/22
1K0
和小伙伴们仔细梳理一下 Spring 国际化吧!从用法到源码!
js将json字符串转换成json对象_java中将字符串转换为json
private static String dateformat = “yyyy-MM-dd hh:mm:ss”;
全栈程序员站长
2022/11/08
5.7K0
Java时间操作代码实现
OK,本文的主题是java中常用的时间操作,在平时开发过程中经常会使用到这些时间操作类,但是大部分使用都是其他工具包提供的类或者就那么几个常用的方法,对其中的方法也都并没有深入学习。所以这篇博客就记录一下我对jdk8中有关常用的时间操作的学习,在此过程中会用到jdk文档。
beifengtz
2019/06/03
6980
推荐阅读
相关推荐
Spring周边:国际化、Format
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档