2011-03-08 39 views
0

我遇到以下程序並顯示意外的結果。Java問題:從字節序列創建字符串

public class StringFromByte 
{ 
     public static void main(String[] args) 
     { 
      byte bytes[] = new byte[256]; 

      for(int i = 0; i < 256; i++) 
       bytes[i] = (byte)i; 

      String str = new String(bytes); 
      for(int i = 0, n = str.length(); i < n; i++) 
       System.out.print((int)str.charAt(i) + " "); 
     } 
} 

從技術上講,這個程序應該按順序打印從0到255的整數。但是如果你運行程序有時會顯示這個序列(0到255),有時它會顯示一些其他序列。它的行爲沒有指定。這是怎麼回事?

+1

我無法解釋非確定性行爲,但我確實看到一個問題。如果將int值超過127轉換爲一個字節,那麼它實際上是一個負值,當返回到一個int時保持負值,因此即使這是確定性的,也不會返回0 - > 255打印出來。這甚至不涉及將隨機字節投入字符串時發出的編碼。 – rfeak

回答

2

您正在使用的字符串構造函數使用默認的字符編碼。它可以將一些字節解釋爲多字節字符。

試試這個:

  String str = new String(bytes, CharSet.forName("ISO-8859-1")); 

CharSet API documentation見,其中列出了標準charset名稱。

聲明:我通常使用這個構造函數爲UTF-8。

+0

但是編碼在運行時如何改變?正如Umesh提到的,「有時」順序會改變。跨運行的編碼效果不應該保持相同嗎? – peakit

+0

@peakit,目前尚不清楚是否所有運行在相同平臺上的相同選項。 –

0

那麼,對於初學者來說,類型可以容納的最大值是127(字節數據類型是一個8位有符號二進制補碼整數)。

+0

因此,如果您將這些字節的int整數替換爲-127和127之間的整數,您是否會得到預期的結果? –

1

其行爲不是未指定的。

字符與字節不是一回事,但寫這個的人不知道。 unicode中有大約600萬個字符,但只有256個唯一字節。這意味着許多unicode字符都由多個字節表示。

您示例中的一些字節表示該字符需要多個字節,但我猜測數組中的「下一個」字節不符合有效的UTF-8字符。

要正確編碼來自不是UTF-8,use this constructor的一組字節的字符串。 您將必須提供正確的字符集,以便Java可以瞭解字節如何適合字符。

你得到不同結果的原因是因爲環境。每個環境都有一個默認的Locale來指定它的首選字符集。您使用的構造函數總是採用UTF-8字符集,因此有時會將源字節誤譯爲亂碼。

0

byte替換爲char並且其按預期工作。這是因爲字節的最大值爲127.