亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

char[] 到 byte[] 背后的 Java 11 Compact Strings 魔術

char[] 到 byte[] 背后的 Java 11 Compact Strings 魔術

慕田峪4524236 2022-07-20 12:13:56
在過去的兩天里,我一直在閱讀有關編碼 Unicode Java 9 緊湊字符串的信息,我感覺很好。但是有些東西我不明白。關于字節數據類型1)。是一個 8 位存儲范圍從 -128 到 127問題1)。為什么Java沒有像char unsigned 16 bits那樣實現它?我的意思是它會在 0.256 的范圍內,因為從 0 到 127 我只能保存一個 Ascii 值,但是如果我將值設置為 200 會發生什么,擴展的 ascii 會溢出到 -56。2)。負值是否意味著我的意思是我嘗試了一個使用 Java 11 的簡單示例final char value = (char)200;//in byte would overflowfinal String stringValue = new String(new char[]{value});System.out.println(stringValue);//THE SAME VALUE OF JAVA 8我檢查了 String.value 變量,我看到了一個字節數組System.out.println(value[0]);//-56出現與之前相同的問題,-56 是否意味著其他語言中的(負值)這個溢出被檢測到返回值 200?Java 怎么知道 -56 值與 char 中的 200 相同。我嘗試了最難的例子,比如代碼點 128048,我在 String.value 變量中看到了一個這樣的字節數組。0 = 61 1 = -402 = 483 = -36我知道這個代碼點需要 4 個字節,但我知道如何將 char[] 轉換為 byte[] ,但我不知道 String 如何處理這個 byte[] 數據。對不起,如果這個問題很簡單,對不起,任何打字英語都不是我的自然語言,非常感謝。
查看完整描述

2 回答

?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

為什么Java沒有像char unsigned 16 bits那樣實現它?我的意思是它會在 0.256 的范圍內,因為從 0 到 127 我只能保存一個 Ascii 值,但是如果我將值設置為 200 會發生什么,擴展的 ascii 會溢出到 -56。


Java 的原始數據類型在 25 年前的 Java 1.0 中得到了解決。不到兩年前,Java 9 中引入了緊湊字符串。這個新特性只是一個實現細節,并不能證明 Java 類型系統的根本變化是合理的。


除此之外,您正在查看存儲在一個字節中的數據的一種解釋。為了表示 iso-latin-1 單位,將相同的數據解釋為 Java 內置的 signedbyte是否會導致正數或負數完全無關緊要。


同樣,Java 的 I/O API 允許將文件讀入byte[]數組并將數組寫byte[]回文件,這兩個操作已經足以無損地復制文件,而不管其文件格式在解釋其內容時是否相關。


所以從 Java 1.1 開始以下工作:


byte[] bytes = "è".getBytes("iso-8859-1");

System.out.println(bytes[0]);

System.out.println(bytes[0] & 0xff);

-56

200

這兩個數字,-56和200只是位模式的不同解釋,而包含位模式的11001000iso-latin-1 解釋是字符。byte11001000è


值char也只是對兩個字節數量的解釋,即作為 UTF-16 代碼單元。同樣,char[]數組是計算機內存中具有標準解釋的字節序列。


我們也可以用這種方式解釋其他字節序列。


StringBuilder sb = new StringBuilder().appendCodePoint(128048);

byte[] array = new byte[4];

StandardCharsets.UTF_16LE.newEncoder()

    .encode(CharBuffer.wrap(sb), ByteBuffer.wrap(array), true);

System.out.println(Arrays.toString(array));

將打印您看到的值,[61, -40, 48, -36].


在類中使用byte[]數組的優點String是,現在可以選擇解釋,當所有字符都可以用這種編碼表示時使用 iso-latin-1,否則使用 utf-16。


可能的數字解釋與字符串無關。但是,當你問“Java 怎么知道 -56 值與 200 相同”時,你應該問自己,它是如何知道11001000abyte的位模式-56在首位的?


System.out.println(value[0]);

與普通計算機算術相比,a byte(或 an int)到 a的轉換實際上是一個昂貴的操作String。這種轉換操作經常被忽略,因為它已被定義為打印 a 的默認方式,但并不比將值解釋為無符號數量byte的轉換更自然。String為了進一步閱讀,我推薦二進制補碼。


查看完整回答
反對 回復 2022-07-20
?
jeck貓

TA貢獻1909條經驗 獲得超7個贊

這是因為并非字符串中的所有字節都被解釋為相同的。這取決于字符串的字符編碼。

例子:

  • 如果字符串是 UTF-8 字符串,則其字符大小為 8 位。

  • 在 UTF-16 字符串中,其字符大小為 16 位。

  • ETC...

這意味著,如果要將字符串表示為 UTF-8,則字符將通過一次讀取 1 個字節來生成;如果是 16 位,則字符將通過一次讀取 2 個字節來生成。

看這段代碼:data使用 UTF-8 和 UTF-16 將單字節數組轉換為字符串。

byte[] data = new byte[] {97, 98, 99, 100};

System.out.println(new String(data, StandardCharsets.UTF_8));

System.out.println(new String(data, StandardCharsets.UTF_16));

這段代碼的輸出是:


abcd // 4 bytes = 4 chars, 1 byte per char

慢捤  // 4 bytes = 2 chars, 2 byte per char

回到這個問題,開發人員這樣做的動機是減少字符串的內存占用。并非所有字符串都使用所有 16 位 achar報價。


查看完整回答
反對 回復 2022-07-20
  • 2 回答
  • 0 關注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號