簡體   English   中英

為什么Java的String.getBytes()使用“ISO-8859-1”

[英]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()返回字節。

  • 默認字符集由系統file.encoding屬性提供。
  • 這是緩存的,在JVM啟動后通過System.setProperty(..)更改它是沒有用的。
  • 如果file.encoding屬性未映射到已知的字符集,則指定UTF-8。

....這是棘手的部分(可能永遠不會發揮作用)....

如果系統無法使用默認字符集(UTF-8或其他字符串)對字符串進行解碼或編碼,則將回退到ISO-8859-1。 如果后備不起作用......系統將失敗!

....真的......(喘息!)......如果我的指定字符集無法使用,UTF-8或ISO-8859-1也無法使用,它會崩潰嗎?

是。 String源碼注釋狀態在StringCoding.encode(...)方法中:

//如果我們找不到ISO-8859-1(一個必需的編碼)那么安裝就會出現嚴重問題。

...然后調用System.exit(1)


那么,為什么在getBytes()方法中有意回退ISO-8859-1?

雖然不太可能,但用戶JVM可能不支持UTF-8中的解碼和編碼或JVM啟動時指定的字符集。

那么,在getBytes()期間,String類中是否正確使用了默認字符集?

不。但是,更好的問題是......


String.getBytes()是否提供了它所承諾的功能?

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM