[英]Does Java's String.getBytes(“ISO-8859-1”) return the first byte of each 2-byte character in a string?
[英]Why does Java's String.getBytes() uses “ISO-8859-1”
來自java.lang.StringCoding:
String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
這是從Java.lang.getBytes()中使用的,在linux jdk 7中我總是認為UTF-8是默認的字符集?
謝謝
Java 嘗試使用默認字符編碼來使用String.getBytes()返回字節。
....這是棘手的部分(可能永遠不會發揮作用)....
如果系統無法使用默認字符集(UTF-8或其他字符串)對字符串進行解碼或編碼,則將回退到ISO-8859-1。 如果后備不起作用......系統將失敗!
....真的......(喘息!)......如果我的指定字符集無法使用,UTF-8或ISO-8859-1也無法使用,它會崩潰嗎?
是。 String源碼注釋狀態在StringCoding.encode(...)方法中:
//如果我們找不到ISO-8859-1(一個必需的編碼)那么安裝就會出現嚴重問題。
...然后調用System.exit(1)
雖然不太可能,但用戶JVM可能不支持UTF-8中的解碼和編碼或JVM啟動時指定的字符集。
那么,在getBytes()期間,String類中是否正確使用了默認字符集?
不。但是,更好的問題是......
Javadoc中定義的合同是正確的。
未指定此字符串無法在默認字符集中進行編碼時此方法的行為。 當需要對編碼過程進行更多控制時,應使用
CharsetEncoder
類。
始終建議明確指定“ISO-8859-1”或“US-ASCII”或“UTF-8”或將字節轉換為字符串時所需的任何字符集,反之亦然 - 除非 - 您之前已獲得默認的charset並100%確定它是你需要的。
請改用此方法:
public byte[] getBytes(String charsetName)
要查找系統的默認值,只需使用:
Charset.defaultCharset()
希望有所幫助。
默認情況下,無參數的String.getBytes()
方法不使用ISO-8859-1。 如果可以確定,它將使用默認平台編碼。 但是,如果丟失或者是無法識別的編碼,則它將作為“默認默認值”回退到ISO-8859-1。
你應該很少在實踐中看到這一點。 通常,將正確檢測平台默認編碼。
但是,我強烈建議您在每次執行編碼或解碼操作時指定顯式字符編碼。 即使您希望平台默認,也請明確指定。
這是出於兼容性的原因。
從歷史上看,Windows和Unix上沒有指定字符集的所有Java方法當時都使用了常見的方法,即"ISO-8859-1"
。
正如Isaac和javadoc所提到的,使用了默認的平台編碼(參見Charset.java ):
594 public static Charset defaultCharset() {
595 if (defaultCharset == null) {
596 synchronized (Charset.class) {
597 String csn = AccessController.doPrivileged(
598 new GetPropertyAction("file.encoding"));
599 Charset cs = lookup(csn);
600 if (cs != null)
601 defaultCharset = cs;
602 else
603 defaultCharset = forName("UTF-8");
604 }
605 }
606 return defaultCharset;
607 }
始終在執行字符串到字節或字節到字符串轉換時指定字符集。
即使像String.getBytes()
的情況一樣,你仍然會發現一個不推薦使用charset的非棄用方法(當Java 1.1出現時,大多數方法都被棄用了)。 就像字節順序一樣,平台格式無關緊要,相關的是存儲格式的規范。
詳細說明Skeet的答案(當然是正確答案)
在java.lang.String的源代碼中, getBytes()
調用StringCoding.encode(char[] ca, int off, int len)
,它在第一行有:
String csn = Charset.defaultCharset().name();
然后(不是立即但絕對)它調用static byte[] StringEncoder.encode(String charsetName, char[] ca, int off, int len)
,其中引用的行來自 - 作為charsetName傳遞csn - 所以在這一行charsetName
將是默認字符集(如果存在)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.