執行內容:
String a = "select * from j_question j where j.status = %s and j.title like '%java%'";
String format = String.format(a, 1);
System.out.println(format);
拼接SQL時,最后需要 format 替換字符串中的 %s 占位符。
預期效果:
select * from j_question j where j.status = 1 and j.title like '%java%'
報錯內容:
Conversion = 'j' 或者是 Conversion = 'D' 或者 Conversion = 'Y'
Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = 'j'
at java.base/java.util.Formatter$FormatSpecifier.conversion(Formatter.java:2839)
at java.base/java.util.Formatter$FormatSpecifier.<init>(Formatter.java:2865)
at java.base/java.util.Formatter.parse(Formatter.java:2713)
at java.base/java.util.Formatter.format(Formatter.java:2655)
at java.base/java.util.Formatter.format(Formatter.java:2609)
at java.base/java.lang.String.format(String.java:2897)
錯誤原因:
String.format() 格式化字符串輸出時,任何未明確定義為轉換的字符都是非法的,在格式字符串中使用此類字符將導致 UnknownFormatConversionException。
1、先來明確一下 % 的作用:
% 就相當於一種語法格式, % 后面需要跟上需要轉換的參數,而參數的取值,無非就如下這些情況:
轉換 | 參數類別 | 說明 |
---|---|---|
'b','B' | 常規 | 如果參數 arg 為 null,則結果為 "false"。如果 arg 是一個 boolean 值或 Boolean,則結果為 String.valueOf() 返回的字符串。否則結果為 "true"。 |
'h','H' | 常規 | 如果參數 arg 為 null,則結果為 "null"。否則,結果為調用 Integer.toHexString(arg.hashCode()) 得到的結果。 |
's', 'S' | 常規 | 如果參數 arg 為 null,則結果為 "null"。如果 arg 實現 Formattable,則調用 arg.formatTo。否則,結果為調用 arg.toString() 得到的結果。 |
'c','C' | 字符 | 結果是一個 Unicode 字符 |
'd' | 整數 | 結果被格式化為十進制整數 |
'o' | 整數 | 結果被格式化為八進制整數 |
'x', 'X' | 整數 | 結果被格式化為十六進制整數 |
'e','E' | 浮點 | 結果被格式化為用計算機科學記數法表示的十進制數 |
'f' | 浮點 | 結果被格式化為十進制數 |
'g','G' | 浮點 | 根據精度和舍入運算后的值,使用計算機科學記數形式或十進制格式對結果進行格式化。 |
'a','A' | 浮點 | 結果被格式化為帶有效位數和指數的十六進制浮點數 |
't', 'T' | 日期/時間 | 日期和時間轉換字符的前綴。請參閱日期/時間轉換。 |
'%' | 百分比 | 結果為字面值 '%' ('"u0025') |
'n' | 行分隔符 | 結果為特定於平台的行分隔符 |
2、再來解釋一下什么是未明確定義的字符:
通過上面這些取值我們知道了,%[參數] 頂多就 %b、%B、%h、%H、%s、%S ... %%、%n 等。
而在需要轉換的字符串中有這么一段 %java%
,也就是他會把 %j
當做一個轉換參數,很顯然上邊的取值中就沒有 %j
嘛,所以就報錯了,就如同錯誤內容一樣:Conversion = 'j'
那么需要用到 % 的地方怎么辦呢?
解決方法:
通過上邊的 % 取值發現,%%
最終的輸出結果為一個 %,所以解決方法就是使用雙重 %,
比如之前的 %java%
,需要修改為 %%java%%
String a = "select * from j_question j where j.status = %s and j.title like '%%java%%'";