本文主要說明java的系統里字符串(string)的編碼的情況
首先一個問題,如何知道某個string(變量的值)的編碼是什么?情況復雜,下面分開說明
首先要知道系統默認編碼(“系統”不是指操作系統,而是本java應用)。影響編碼有以下情況:
默認時,就是操作系統的編碼,我們用的中文windows編碼一般是GBK,而linux一般是utf-8
當java啟動命令可以指定具體編碼。我們生產環境一般都會設為utf-8。編碼設置方法在開發和生產環境有不同方法,對於開發環境,編碼的設置跟開發用的IDE有關,這里不展開,對於生產環境,編碼設置在java運行命令的參數
-Dfile.encoding=utf-8
上面說的是編碼設置,那怎么確定java應用真實使用的編碼(確認設置是否生效)?可以用如下代碼輸出
//獲取系統默認編碼 logger.info("系統默認編碼:" + System.getProperty("file.encoding")); //系統默認字符編碼 logger.info("系統默認字符編碼:" + Charset.defaultCharset()); //操作系統用戶使用的語言 logger.info("系統默認語言:" + System.getProperty("user.language"));
在我自己的IDEA開發環境運行輸出如下。因為在IDEA的配置設了編碼是utf-8
PS:【系統默認編碼】和【系統默認字符編碼】到底哪個才影響“string的編碼”還不清楚,弄的兩個都一樣的就最好了
到此,我們解決了java應用默認編碼的問題,“在代碼中顯式賦值的string“的編碼都是默認編碼,例如下圖這些就是
但是,string的值來源很多,例如有從配置文件讀取,從http調用(作為服務端)傳入,從excel或文本文件讀取等等。此時string的編碼跟文件本身的編碼甚至讀取的相關工具類的編碼設置都有關,這里不展開怎么修改編碼。但怎么確認他們是什么編碼?可以用以下方法
PS:此方法在實際使用中發現不太准確,因此還有待驗證
public static final String[] ENCODES = new String[]{"UTF-8", "GBK", "GB2312", "ISO-8859-1", "ISO-8859-2"}; /** * 獲取字符串是什么編碼,例如返回的值有:UTF-8,GBK,ISO-8859-1等 * * @param str * @return */ public static String getEncode(String str) { byte[] data = str.getBytes(); byte[] b = null; a: for (int i = 0; i < ENCODES.length; i++) { try { b = str.getBytes(ENCODES[i]); if (b.length != data.length) { continue; } for (int j = 0; j < b.length; j++) { if (b[j] != data[j]) { continue a; } } return ENCODES[i]; } catch (UnsupportedEncodingException e) { continue; } } return null; }
輸出如下,