Java中的byte/char/String數據類型轉換

前言:項目中遇到了一個問題,Android手機和硬件建立Socket通信,當手機批量發送數據時,發送頻率高於單片機接收報文進入中斷處理的頻率,導致硬件處理不過來。解決的方法是將原先的String類型的大量報文包含的信息,簡化成一條十六進制的報文。

在解決完這個問題後,才意識到Java中數據類型轉換的重要性,而且Java和C之間的Socket通信最好全部由字節來實現,所以post一篇心得和經驗。


一、 字符編碼方式及類型轉換簡介

通常意義上的字符和數字所代表的含義和機器語言是有出入的。對機器而言,“數字”只有代表高低電平的0或1;而無論1~9,a~z,A~Z,漢字,拉丁字母,希臘字母等等,都被視爲“字符”。編碼,就是將這些“字符”和固定長度的0、1組合唯一對應起來。

常用的編碼方式有Unicode、ASCII、UTF-8、GB2312、ISO-8899-1等。採用不同的編碼方式,同樣的n位二進制“數字”組合代表的“字符”也會不一樣。具體採用什麼樣的編碼方式,對“字符”怎樣解析,就要看編程所在的平臺是什麼樣了。同時,爲了方便,我們並不會直接用n位二進制的“數字”表示,而是用它的十六進制“數字”表示。

在介紹Java平臺下的數據類型轉換時,本文涉及到了Unicode、ASCII、GB2312、ISO-8899-1,簡單說明如下:

  1. Java內核採用Unicode編碼,Unicode又稱爲萬國碼、統一碼,是完全國際化的字符集,可以表示全部人類語言中的字符。

  2. Unicode編碼方式是雙字節編碼,即每個字符=兩個字節=16位數,存儲範圍在\u0000~\uFFFF。表示一個Unicode的字符時,通常會用“\u”然後緊接着一組十六進制的數字來表示這一個字符

  3. 在Java中,有以下八種基本數據類型

    (1) byte、int、short之間不會互相轉換,因爲容量小的數據類型會自動轉換爲大的數據類型,所以在運算時,它們都會被轉換爲int型

    (2)容量大的數據類型轉換成容量小的數據類型時,要加上強制轉換符,但可能會造成精度降低或數據溢出

    (3)Java中的類型轉換總結來說就是 整型-字符型-String 之間的轉換

    (4)String不屬於Java的基本數據類型,String的本質是字符數組,是類對象

    數據類型 名稱 長度 備註
    byte 字節型 1字節 = 8bit 表示數據範圍:-128~127
    short 短整型 2字節 = 16bit
    char 字符型 2字節 = 16bit 等價於Unicode編碼
    int 整型 4字節 = 32bit
    long 長整型 8字節
    float 單精度浮點型 4字節 精度:7-8位
    double 雙精度浮點型 8字節
    boolean 布爾型 true/false

二、 byte\char轉換和Unicode編碼

  1. 從上面的表中,我們已經知道了char是2字節,byte是1字節,舉例說明如下:

    char a=’中’ 合法:在GB2312編碼方式中,一箇中文字符=2字節
    char a=’ab’ 非法:儘管一個char佔用2字節,但是隻能表示一個字符
    byte a=’中’ 非法:1字節不能存放中文字符
    byte a=’a’ 合法:一個字符=1字節

  2. 測試Demo:輸入Unicode,分別轉換成ISO、GB2312、ASCII編碼代表的字符

(1) 程序

輸入包括:2位byte=1箇中文字符;1位byte=1個字符,並通過不同編碼方式轉碼不同成字符


private void Byte2Char() {
    // TODO Auto-generated method stub
    byte b[] = {(byte)'\u0080',(byte)'\u0001',(byte)'\u007f',(byte)'\u00ff',(byte)'\u00BA',(byte)'\u00CF'};             
    /**
     *  通過ByteToCharConverter類轉換不可行,sun.io.*包屬於內部API,已經不可用
     *  ByteToCharConverter converter = ByteToCharConverter.getConverter("gb2312");
     *  char c[] = converter.convertAll(b);         
     */         

    Charset charSet = Charset.forName("8859_1");
    ByteBuffer byteBuffer = ByteBuffer.allocate(b.length);
    byteBuffer.put(b);
    byteBuffer.flip();
    CharBuffer charBuffer = charSet.decode(byteBuffer);

    textView1.setText("Byte2Char() 單字節編碼 ISO-8899-1"
            +"\n"+"目標格式:"+charSet
            +"\n"+"輸入4字節byte:0080 0001 007f 00ff 00BA 00CF "
            +"\n"+"輸出Char字符:"+charBuffer
            +"\n"+"byte型8位2進制:"+b[0]+"/"+b[1]+"/"+b[2]+"/"+b[3]+"/"+b[4]+"/"+b[5]
            );
}

(2)輸出

Unicode、byte和char

注:ISO-8899-1轉碼時Log有誤,“輸入4字節byte”應改爲“輸入6字節byte”


三、 Java中的String類

下面是String源碼類註釋中的一段話:

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.

同時,String類還使用了final修飾符,下面是String類的成員變量定義:

private final char value[]
private final int count

String的實質就是字符數組,以上內容包含了String的三個特點:
(1)String是值不可變的常量
(2)String是線程安全的
(3)String類是不可繼承的


五、 參考資料

[1] http://blog.csdn.net/yutianzuijin/article/details/24807417
作者和我遇到的問題是一樣的:Java和C之間建立Socket通信的方案,數據格式不統一是很重要的問題
[1] http://blog.csdn.net/taohuaxinmu123/article/details/12099105
這篇博客詳細介紹了Java基本數據類型及轉換,基本數據類型的對象包裝器
[2]
http://blog.csdn.net/lpali/article/details/5405203
這篇博客清楚的介紹了作者對於“字符”和“數字”,Java和C,Unicode和其它編碼方式的理解
[3] http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
這篇文章介紹了Unicode編碼,寫得很好
[4] http://my.oschina.net/xiaohui249/blog/170013
這篇文章後半部分深入介紹了Java中的String類

發佈了37 篇原創文章 · 獲贊 15 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章