1. 程式人生 > >Java記憶體中的字元編碼

Java記憶體中的字元編碼

  Java記憶體中的字元編碼

Unicode字符集及utf-8 、utf-16、utf-32 等字元編碼方式

字符集:字元表示的數字集合,元素稱為碼點或碼位;

字元編碼:字元實際的儲存表示;

碼點:一個碼點對應 一個字元;

 

utf-8編碼:可變長編碼,一個字元編碼使用 1或2或3或4個位元組表示; https://blog.csdn.net/hezh1994/article/details/78899683

utf-32編碼:定長編碼,一個字元編碼使用4個位元組

utf-16編碼:結合可變長編碼及定長編碼,BMP平面字元編碼2個位元組,SMP平面字元比編碼使用4位元組; 

 

 

Java記憶體中字元(char變數或String(char[]))以utf-16BE編碼存在

 

  utf-16 BMP平面(代理區U+0000至U+FFFF除外)的碼點,以1個碼元(16位元即2位元組)編碼;SMP平面的碼點以2個碼元(32位元)編碼
因此Java記憶體中char型別變數只能表示BMP平面的一個字元,表示SMP平面的字元使用String物件。 

String str = new String(Character.toChars(0x1D56B)); // 一個字元

 

字元從記憶體輸出,如何顯示在螢幕 ?

//System.out.println(strings);

System.out.print() 將記憶體中的字串(char[])按utf-16解碼為unicode碼點,再以系統編碼方式(如utf-8,將碼點編碼)輸出位元組流,
控制檯收到的位元組流,以相同的方式(utf-8)解碼為unicode碼點
系統將碼點以圖形的形式顯示

 

 

測試程式碼

(1)SMP平面字元

String str = new String(Character.toChars(0x1D56B)); //UTF-16 representation stored ,所以這個unicode擴充套件字元儲存在記憶體的需要 2個char

System.out.println("碼點: "+Integer.toHexString(str.codePointAt(0)));
System.out.println("utf-8編碼的記憶體形式: 位元組數量 "+str.getBytes().length); //4
System.out.println("utf-8編碼的記憶體形式: 位元組序列 "+Arrays.toString(str.getBytes())); //IDE設定使用 utf-8
System.out.println("utf-16編碼的記憶體形式: 雙位元組(碼元)數量 "+str.toCharArray().length); //2
System.out.println("utf-16編碼的記憶體形式: 雙位元組(碼元)序列 "+"["+Integer.toHexString((int)str.charAt(0))+","+Integer.toHexString((int)str.charAt(1))+"]");
//System.out.println(str.toCharArray()); //顯示為特殊字元
System.out.println("字串長度(碼元): "+str.length()); //2 java統計字串長度實際是計算char[]陣列長度(碼元總數),而不是字元(碼點)個數
System.out.println("字串字元(碼點)個數: "+str.codePointCount(0,str.length())); //1

 

輸出結果:

碼點: 1d56b
utf-8編碼的記憶體形式: 位元組數量 4
utf-8編碼的記憶體形式: 位元組序列 [-16, -99, -107, -85]
utf-16編碼的記憶體形式: 雙位元組(碼元)數量 2
utf-16編碼的記憶體形式: 雙位元組(碼元)序列 [d835,dd6b]
字串長度(碼元): 2
字串字元(碼點)個數: 1

 

(2)BMP平面字元

String s = new String(Character.toChars(0x4f60));
System.out.println("碼點: "+Integer.toHexString(s.codePointAt(0)));

System.out.println("utf-8編碼的記憶體形式: 位元組數量 "+s.getBytes().length); //3
System.out.println("utf-8編碼的記憶體形式: 位元組序列 "+Arrays.toString(s.getBytes())); //IDE設定使用 utf-8
System.out.println("utf-16編碼的記憶體形式: 雙位元組(碼元)數量 "+s.toCharArray().length); //1
System.out.println("utf-16編碼的記憶體形式: 雙位元組(碼元)序列 "+"["+Integer.toHexString((int)s.charAt(0))+"]");
System.out.println("字串長度(碼元): "+s.length()); //1 java統計字串長度實際是計算char[]陣列長度(碼元總數),而不是字元(碼點)個數
System.out.println("字串字元(碼點)個數: "+s.codePointCount(0,s.length())); //1

輸出結果:

碼點: 4f60
utf-8編碼的記憶體形式: 位元組數量 3
utf-8編碼的記憶體形式: 位元組序列 [-28, -67, -96]
utf-16編碼的記憶體形式: 雙位元組(碼元)數量 1
utf-16編碼的記憶體形式: 雙位元組(碼元)序列 [4f60]
字串長度(碼元): 1
字串字元(碼點)個數: 1