Java格式化輸出printf()解讀
本文通過實(shí)例詳細(xì)介紹Java格式化輸出 System.out.printf() 方法的使用、參數(shù)的含義、格式轉(zhuǎn)換符使用時(shí)的注意事項(xiàng)。
1. printf API
// 使用指定的格式字符串和參數(shù)將格式化字符串寫入入到輸出流 public PrintStream printf(String format, Object ... args) // 基于本地化環(huán)境使用指定的格式字符串和參數(shù)將格式化字符串寫入到輸出流 public PrintStream printf(Locale l, String format, Object ... args)
以上2個(gè)方法,當(dāng) format 為 null 時(shí),拋出 NPE.
2. 參數(shù)說明
format
format 是以百分號(hào)(%) 開頭的格式說明字符串,具體格式如下
%[argument_index$][flags][width][.precision]conversion
可選的 argument_index 是十進(jìn)制整數(shù),表示參數(shù)列表中參數(shù)的位置。 第一個(gè)參數(shù)由“ 1$
”引用,第二個(gè)由“ 2$
” 引用 ,等等。 argument_index 必須緊跟 %
后面,并以 $
結(jié)束。
note: 參數(shù)索引值從1開始,而不是從0開始, %1$
對(duì)第一個(gè)參數(shù)格式化。這就避免了與0標(biāo)志混淆。
可選 flags 指定格式化輸出外觀的各種標(biāo)志。 有效標(biāo)志集取決于 conversion。
可選 width是正十進(jìn)制整數(shù),表示要寫入到輸出的字符個(gè)數(shù)(注意對(duì)于浮點(diǎn)數(shù):也包含小數(shù)點(diǎn)所占的1個(gè)字和 負(fù)數(shù)的負(fù)號(hào)所占的1個(gè)字符)。 當(dāng)實(shí)際字符數(shù)小于指定的寬度時(shí),最前面用 flags 指定的標(biāo)志填充(若未指定,默認(rèn)用空格)。
eg: v=2.3, %5.2f
輸出 5.20
,且前面包含1個(gè)空格。共打印5個(gè)字符,整數(shù)位1個(gè)5,1個(gè)小數(shù)點(diǎn),2個(gè)精度,長度為4,比指定的寬度少1為,用1個(gè)前導(dǎo)空格代替。
可選 precision 是一個(gè)非負(fù)十進(jìn)制整數(shù),通常用于限制字符數(shù)。 具體行為取決于轉(zhuǎn)換。
conversion (必需) 是一個(gè)字符,指示如何格式化參數(shù)。 給定參數(shù)的有效轉(zhuǎn)換集取決于參數(shù)的數(shù)據(jù)類型。
- 表1-用于printf flags(標(biāo)志) 說明
標(biāo)志 | 目的 | 示例 |
---|---|---|
+ | 打印正數(shù)和負(fù)數(shù)的符號(hào) | +3333.33 |
空格 | 在正數(shù)之前添加空格 | | 3333.33| |
0 | 數(shù)字前面補(bǔ)0 | 003333.33 |
- | 左對(duì)齊(不指定-時(shí),默認(rèn)為右對(duì)齊) | |3333.33 | |
( | 將負(fù)數(shù)括在括號(hào)內(nèi) | %d,-90輸出(90) |
,(英文逗號(hào)) | 添加分組分隔符,只對(duì)定點(diǎn)浮點(diǎn)數(shù)整數(shù)部分添加分組分隔符,小數(shù)部分不會(huì)添加 | 3,333.33 |
#(對(duì)于f格式) | 包含小數(shù)點(diǎn) | 3,333. |
#(對(duì)于x或o格式) | 添加前綴0x或0 | 0xcafe |
$ | 指定要格式化的參數(shù)索引。例如,%1 d d %1 dx 將以十進(jìn)制和十六進(jìn)制格式打印第1個(gè)參數(shù) | 159 9F |
< | <格式化前面說明的數(shù)值。例如, %d<%x 將以十進(jìn)制和十六進(jìn)制打印同一個(gè)值 | 159 9F |
- 表2-用于printf conversion(轉(zhuǎn)換符) 說明
轉(zhuǎn)換符 | 類型 | 示例 | 轉(zhuǎn)換符 | 類型 | 示例 |
---|---|---|---|---|---|
d | 十進(jìn)制整數(shù) | 159 | s | 字符串 | hello |
x | 十六進(jìn)制整數(shù) | 9f | c | 字符 | H |
o | 八進(jìn)制整數(shù) | 237 | b | 布爾 | true |
f | 定點(diǎn)浮點(diǎn)數(shù) | 1.59e+01 | h | 散列碼 | 42628b2 |
e | 指數(shù)浮點(diǎn)數(shù) | tx或Yx | 日期時(shí)間(T強(qiáng)制大寫) | 已經(jīng)過時(shí),應(yīng)當(dāng)改為使用 java.time 類。 | |
g | 通用浮點(diǎn)數(shù)(e和f中較短的一個(gè)) | —— | % | 百分號(hào) | % |
a | 16進(jìn)制浮點(diǎn)數(shù) | 0x1.fccdp3 | n | 與平臺(tái)有關(guān)的換行符 | —— |
補(bǔ)充1: 使用 s 轉(zhuǎn)換符格式化任意的對(duì)象
可以使用 s 轉(zhuǎn)換符格式化任意的對(duì)象。 對(duì)于實(shí)現(xiàn)了 Formattable 接口的任意對(duì)象,將調(diào)用這個(gè)對(duì)象的 formatTo 方法;否則調(diào)用 toString 方法將這個(gè)對(duì)象轉(zhuǎn)換為字符串。
補(bǔ)充2: String.format()
使用 String.format()
方法可創(chuàng)建一個(gè)格式化的字符串,而不打印輸出。
API:
public static String format(String format, Object... args) public static String format(Locale l, String format, Object... args)
參數(shù)和 printf() 中的含義相同。
表3-日期和時(shí)間的轉(zhuǎn)換符
Note: 以下格式符已經(jīng)過時(shí),對(duì)于新的代碼,應(yīng)當(dāng)使用 java.time 包的方法。
eg:
System.out.printf("%tc",new Date());
這條語句將用下面的格式打印當(dāng)前的日期和時(shí)間:
Mon Feb 09 18:05:19 PST 2015
下面的轉(zhuǎn)換符前面都必須用 t/T 修飾。
轉(zhuǎn)換符 | 類型 | 示例 |
---|---|---|
c | 完整的日期和時(shí)間 | Mon Feb 09 18:05:19 PST 2015 |
F | ISO 8601日期 | 2015/2/9 |
D | 美國格式的日期(月/日/年) | 02/09/2015 |
T | 24小時(shí)時(shí)間 | 18:05:19 |
r | 12小時(shí)時(shí)間 | 6:05:19 |
R | 24小時(shí)時(shí)間,沒有秒 | 18:05 |
Y | 4位數(shù)字的年(前面補(bǔ)0 | 2015 |
y | 年的后兩位數(shù)字(前面補(bǔ)0) | 15 |
C | 年的前兩位數(shù)字(前面補(bǔ)0) | 20 |
B | 月的完整拼寫 | February |
b或h | 月的縮寫 | Feb |
m | 兩位數(shù)字的月(前面補(bǔ)0) | 02 |
d | 兩位數(shù)字的日(前面補(bǔ)0) | 09 |
e | 兩位數(shù)字的日(前面不補(bǔ)0 | 9 |
A | 星期幾的完整拼寫 | Monday |
a | 星期幾的縮寫 | Mon |
j | 三位數(shù)的年中第幾天(前面補(bǔ)0),在001到366之間 | 069 |
H | 兩位數(shù)字的小時(shí)(前面補(bǔ)0),在0到23之間 | 18 |
k | 兩位數(shù)字的小時(shí)(前面不補(bǔ)0),在0到23之間 | 18 |
I | 兩位數(shù)字的小時(shí)(前面補(bǔ)0),在01到12之間 | 06 |
l | 兩位數(shù)字的小時(shí)(前面不補(bǔ)0),在1到12之間 | 6 |
M | 兩位數(shù)字的分鐘(前面補(bǔ)0) | 05 |
S | 兩位數(shù)字的秒(前面補(bǔ)0) | 19 |
L | 三位數(shù)字的毫秒(前面補(bǔ)0) | 047 |
N | 九位數(shù)字的毫微秒(前面補(bǔ)0) | 047000000 |
p | 上午或下午的標(biāo)志 | pm |
z | 從 GMT 起,RFC 822 數(shù)字位移 | -800 |
Z | 時(shí)區(qū) | PST |
s | 從格林尼治時(shí)間 1970-01-01 00:00:00 起的秒數(shù) | 1078884319 |
Q | 從格林尼治時(shí)間 1970-01-01 00:00:00 起的毫秒數(shù) | 1078884319047 |
從上表可以看到,某些格式只給出了指定日期的部分信息。
例如,只有日期或月份。如果需要多次提供日期來分別格式化每一部分就太笨拙了。
為此,可以用一個(gè)格式字符串指示要格式化的參數(shù)索引。
索引必須緊跟在%后面,并以$終止。
例如,
System.out.printf("%1$s %2$tB %2$te, %2$tY","Due date:",new Date());
會(huì)打印
Due date: February 9, 2015
還可以選擇使用<標(biāo)志。它指示前面格式說明中的參數(shù)將被再次使用。也就是說,以下語句將產(chǎn)生與前面語句同樣的輸出結(jié)果:
System.out.printf("%1$s %tB %<te, %<tY","Due date:",new Date());
args
args : 格式字符串中格式說明符引用的參數(shù)。
如果參數(shù)多于格式說明符,則忽略額外參數(shù)。
參數(shù)的數(shù)量是可變的,可以為零。
參數(shù)的最大數(shù)量受The Java Virtual Machine Specification(java虛擬機(jī)規(guī)范)定義的Java數(shù)組的最大維數(shù)限制。
null參數(shù)上的行為取決于 conversion(轉(zhuǎn)換符) 。
locale
數(shù)字和日期的格式化規(guī)則是特定于本地化環(huán)境的。
例如,在德國,分組分隔符是點(diǎn)號(hào)而不是逗號(hào),另外 Monday被格式化為 Montag。
locale主要用于如何控制應(yīng)用的國際化行為。
3.printf 使用實(shí)例
// +199 199 c7 307 0xc7 0307 System.out.printf("%+d %<d %<x %<o %<#x %<#o\n",199); // | 23| |23| System.out.printf("|% d| |%<d|\n",23); // hello 第5個(gè)字符是o,that's true System.out.printf("%s 第%d個(gè)字符是%c,that's %b\n","hello",5,'o',true); // 15 % 6 = 3 System.out.printf("%2$d %% %1$d = %3$d\n",6,15, 15 % 6); // | 7.33| |007.33| |7.330000| 0x1.d51eb851eb852p2 System.out.printf("|%6.2f| |%0<6.2f| |%<f| %<a\n",7.33); // | 211.79| |211.79 | System.out.printf("|%7.2f| |%<-7.2f|\n",211.79); // | -211.79| |(211.79)| |(-211.79)| System.out.printf("|%8.2f| |%<(8.2f| |(%<.2f)|\n",-211.79); // |-21171.3333| |-21,171.3333| |-2.1171e+04| |-2.117e+04| System.out.printf("|%.4f| |%<,.4f| |%<.4e| |%<.4g|\n",-21171.3333); String str = new String("tree"); // Note: %h 格式符輸出對(duì)象的散列碼 和 調(diào)用對(duì)象的hashCode 得到的值并不相同 // obj %h formatinput: 36739e,hashCode:3568542 System.out.printf("obj %%h formatinput: %h,hashCode:%s\n",str,str.hashCode()); // true 25 0.0032 含 System.out.printf("%s %s %s %s\n",true,25,3.2e-3,'含'); System.out.printf("|%n| \n","world"); System.out.printf("|%n| \n");
輸出
+199 199 c7 307 0xc7 0307
| 23| |23|
hello 第5個(gè)字符是o,that's true
15 % 6 = 3
| 7.33| |007.33| |7.330000| 0x1.d51eb851eb852p2
| 211.79| |211.79 |
| -211.79| |(211.79)| |(-211.79)|
|-21171.3333| |-21,171.3333| |-2.1171e+04| |-2.117e+04|
obj %h formatinput: 36739e,hashCode:3568542
true 25 0.0032 含
|
|
|
|
關(guān)于printf 轉(zhuǎn)換符使用的注意事項(xiàng)
- 適用于浮點(diǎn)類型轉(zhuǎn)換符(e,g,a,f)不能用于整形; 同樣適用于整形的轉(zhuǎn)換符(d,o,x)不能用于浮點(diǎn)型。
- 可以使用 s 轉(zhuǎn)換符格式化任意的對(duì)象。對(duì)于實(shí)現(xiàn)了 Formattable 接口的任意對(duì)象,將調(diào)用這個(gè)對(duì)象的 formatTo 方法;否則調(diào)用 toString 方法將這個(gè)對(duì)象轉(zhuǎn)換為字符串。
eg:
// test in jdk 8,11,14 // Exception in thread "main" java.util.IllegalFormatConversionException: o != java.lang.Float System.out.printf("%o\n",2.3f); // Exception in thread "main" java.util.IllegalFormatConversionException: f != java.lang.Integer System.out.printf("%f\n",25);
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java基于socket實(shí)現(xiàn)的客戶端和服務(wù)端通信功能完整實(shí)例
這篇文章主要介紹了Java基于socket實(shí)現(xiàn)的客戶端和服務(wù)端通信功能,結(jié)合完整實(shí)例形式分析了Java使用socket建立客戶端與服務(wù)器端連接與通信功能,需要的朋友可以參考下2018-05-05一文帶你了解Java創(chuàng)建型設(shè)計(jì)模式之原型模式
原型模式其實(shí)就是從一個(gè)對(duì)象在創(chuàng)建另外一個(gè)可定制的對(duì)象,不需要知道任何創(chuàng)建的細(xì)節(jié)。本文就來通過示例為大家詳細(xì)聊聊原型模式,需要的可以參考一下2022-09-09深入解析java中的靜態(tài)代理與動(dòng)態(tài)代理
本篇文章是對(duì)java中的靜態(tài)代理與動(dòng)態(tài)代理進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2013-10-10Spring Boot項(xiàng)目利用Redis實(shí)現(xiàn)session管理實(shí)例
本篇文章主要介紹了Spring Boot項(xiàng)目利用Redis實(shí)現(xiàn)session管理實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Java調(diào)用參數(shù)類型是application/x-www-form-urlencoded的API問題
在使用Postman進(jìn)行接口測(cè)試時(shí),對(duì)于POST請(qǐng)求,需將請(qǐng)求頭設(shè)置為application/x-www-form-urlencoded,并將參數(shù)轉(zhuǎn)為String類型,通常在GET請(qǐng)求中,參數(shù)直接拼接在URL后,本文通過具體實(shí)例,詳細(xì)講解了參數(shù)處理的方法,適合API開發(fā)者參考2024-09-09struts1實(shí)現(xiàn)簡單的登錄功能實(shí)例(附源碼)
本篇文章主要介紹了struts1實(shí)現(xiàn)簡單的登錄功能實(shí)例(附源碼),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04springboot mybatis里localdatetime序列化問題的解決
這篇文章主要介紹了springboot mybatis里localdatetime序列化問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10Spring Boot整合Spring Data Jpa代碼實(shí)例
這篇文章主要介紹了Spring Boot整合Spring Data Jpa代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11一篇文章掌握J(rèn)ava?Thread的類及其常見方法
Thread類用于操作線程,是所以涉及到線程操作(如并發(fā))的基礎(chǔ)。本文將通過代碼對(duì)Thread類的功能作用及其常見方法進(jìn)行分析2022-03-03