1. 程式人生 > >Java中的byte[]/char[]/int/String資料型別轉換

Java中的byte[]/char[]/int/String資料型別轉換

你也可以檢視我的其他同類文章,也會讓你有一定的收貨!

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

八種基本資料型別:

資料型別 名稱 長度 備註
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

各資料之間轉化:

1.String<—>byte[]

1.1 String—>byte[]

byte[] bytes = mString.getBytes();

String預設使用utf-8編碼,將mString中的二進位制(使用utf-8編碼後的二進位制),每個位元組儲存在bytes中。

例如: mString中的 值:’タ’ 65408 被轉為 bytes 中的 -17, -66 ,-128

65408 對應二進位制 1111 1111 1000 0000,這個資料使用utf-8編碼後的二進位制為:1110 1111 1011 1110 1000 0000,對應- 17,-66, -128

關於編碼,可以檢視我的這篇部落格

1.2 byte[]—>String

//1、預設使用utf-8編碼
String String1 = new String(bytes
); //2、指定其他編碼方式 String String2 = new String(bytes, StandardCharsets.US_ASCII); String String21 = new String(bytes, StandardCharsets.ISO_8859_1);
  • 可以指定byte[]—>String使用的編碼型別
  • String一個字元是16bit,轉化時對byte (8bit)進行符號擴充套件
  • 使用預設的utf-8編碼時,如果byte的二進位制資料不符合utf-8編碼規範,則轉化後 String對應的字元為’�’ 65533

2.String<—>char[]

2.1、String—>char[]

String s = "SSSSSSS";
char[] ss = s.toCharArray();

2.2、char[]—>String

 char[] chars4 = {0x0001, 0xfff0, 0xf0, 'a', 0x4E25};
 String string4 = new String(chars4);
  • char也是使用utf-8編碼,如果char的二進位制資料不符合utf-8編碼規範,使用者看到的字元為空。
  • 因為char已經是字元,所以直接把字元賦給String 。

3.String<—>int

3.1、String—>int

String string9 = "嚴";
int i9 = Integer.parseInt(string9);

Exception in thread “main” java.lang.NumberFormatException: For input string: “嚴”

如果String 不是資料,會丟擲異常

3.2、int—>String

int i = 10;
//轉化
String string9 = String.valueOf(i);
//2、直接使用字串加上i,java會自動轉化
string9 = "" + i;

4.String<—>char

4.1、String—>char

String string = "嚴";
char char = string.charAt(0);

4.2、char—>String

char char1 = a;
//轉化
String string9 = String.valueOf(char1);
//2、直接使用字串加上i,java會自動轉化
string9 = "" + char1;

5.String<—>byte

5.1、String—>byte

可以先轉為String—>byte[],在取出其中的byte

5.1、byte—>String

byte byte1 = 0xff;
//轉化
String string9 = String.valueOf(byte1);
//2、直接使用字串加上i,java會自動轉化,string9 內容為 -1
string9 = "" + byte1;

注意:byte是未經過編碼的二進位制資料,所以在直接轉為String 時,使用者看到的是二進位制對應的十進位制數值

6.int<—>char<—>byte

public static void main(String[] args) {
  byte b=-1;
  System.out.println((int)(char)b);
  System.out.println((int)(char)(b & 0xff));
}

執行結果是:65535和255

如果你對輸出結果感到很驚訝,請繼續往下讀…

1、 int(32位) -> byte(8位)

-1是int型的字面量,根據“2的補碼”編碼規則,編碼結果為0xffffffff,即32位全部置1.轉換成byte型別時,直接擷取最後8位,所以byte結果為0xff,對應的十進位制值是-1.

2、 byte(8位) -> char(16位)

由於byte是有符號型別,所以在轉換成char型(16位)時需要進行符號擴充套件,即在0xff左邊連續補上8個1(1是0xff的符號位),結果是0xffff。由於char是無符號型別,所以0xffff表示的十進位制數是65535。

3、 char(16位) -> int(32位)

由於char是無符號型別,轉換成int型時進行零擴充套件,即在0xffff左邊連續補上16個0,結果是0x0000ffff,對應的十進位制數是65535。

4、 int(32位) -> char(16位)

char c = (char)(b & 0xff);

(b & 0xff)的結果是32位的int型別,前24被強制置0,後8位保持不變,然後轉換成char型時,直接擷取後16位。最後結果為0x00ff

5、 char 與 int 進行運算

int i = c & 0xffff;

0xffff是int型字面量,所以在進行&操作之前,編譯器會自動將c轉型成int型,即在c的二進位制編碼前新增16個0,然後再和0xffff進行&操作,所表達的意圖是強制將前16置0,後16位保持不變。雖然這個操作不是必須的,但是明確表達了不進行符號擴充套件的意圖。

如果需要符號擴充套件,則可以如下編碼:

int i = (short)c; //Cast causes sign extension

首先將c轉換成short型別,它和char是 等寬度的,並且是有符號型別,再將short型別轉換成int型別時,會自動進行符號擴充套件,即如果short為負數,則在左邊補上16個1,否則補上16個0.

Java中資料轉化的一些規則:

  1. 如果二進位制不符合utf-8的規則,在String 中就會被賦值為65533(對應的二進位制)
  2. byte是未經編碼的二進位制資料,在java中可以對byte來進行各種編碼。
  3. 在基本資料型別中,儲存的都是二進位制資料,只是在顯示的時候顯示各自不同的型別。例如:char儲存的二進位制資料顯示出來是使用編碼utf-8後的符號,其它基本資料型別顯示出來都是數字。
  4. 基本資料型別轉String,方式多樣化,

    • 直接相加,
    • String.valueOf()
  5. byte、int、short之間不會互相轉換,因為容量小的資料型別會自動轉換為大的資料型別,所以在運算時,它們都會被轉換為int型

  6. 容量大的資料型別轉換成容量小的資料型別時,要加上強制轉換符,但可能會造成精度降低或資料溢位
  7. String不屬於Java的基本資料型別,String的本質是字元陣列,是類物件

我在進行測試時的程式碼:

public class MyClass {


    public static void main(String[] args) {

        //byte---> string
        //byte是未經過編碼的原始資料,轉為string時可以選擇編碼格式
        byte[] bytes = {0x1f, (byte) 0x7f, (byte) 0xdf80, (byte) 0x80};
//        byte[] packetHeard = {(byte)'\u0080',(byte)'\u0001',(byte)'\u007f',(byte)'\u00ff',(byte)'\u00BA',(byte)'\u00CF'};

        //1、預設使用utf-8編碼
        String String1 = new String(bytes);

        //2、指定其他編碼方式
        String String2 = new String(bytes, StandardCharsets.US_ASCII);
        String String21 = new String(bytes, StandardCharsets.ISO_8859_1);

        //3、使用指定的編碼,把bytes轉為 charBuffer
        Charset charSet = Charset.forName("Unicode");
        ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
        byteBuffer.put(bytes);
        byteBuffer.flip();
        CharBuffer charBuffer = charSet.decode(byteBuffer);


        //4、直接使用tostring(),並不能轉為字串
        String String3 = bytes.toString();
        int i = bytes.hashCode();
        String string31 = Integer.toHexString(i);

        //5、使用char[] 初始化string,char(顯示是utf-8),所以這裡直接使用了這些字元
        //char、int、short等基本型別的資料,都可以直接用二進位制賦值,只是在顯示的時候顯示各自不同的。例如char顯示的是使用編碼utf-8後的符號
        //而把這些資料型別轉化為string時,是根據他們顯示的形式加入的stirng

        char[] chars4 = {0x0001, 0xfff0, 0x80, 'a', 0x4E25};
        short short4 = (short) 0xfff0;
        String string4 = new String(chars4);
        string4 = String.valueOf(short4);

        //6、string  相加,都會保留原來資料屬性(數字就是數字,字元就是字元),可以試著把(char)變為(int)等
        String string5 = "";
        for (i = 0; i < bytes.length; i++) {
            string5 += (char) bytes[i];
        }

        //string-->byte
        //7、預設utf-8編碼,將string5中的二進位制(使用utf-8編碼後的二進位制),每個位元組儲存在bytes6中
        byte[] bytes6 = string5.getBytes();



        //這個所得結果暫時搞不懂
        charSet = Charset.forName("ASCII");
        bytes6 = string4.getBytes(charSet);



        byte[] b = new byte[2];
        b[0] = (byte) ((chars4[4] & 0xFF00) >> 8);
        b[1] = (byte) (chars4[4] & 0xFF);



        //8、
        byte b8 = -1;
        System.out.println((int) (char) b8);
        System.out.println((int) (char) (b8 & 0xff));


        //9
        String string9 = "嚴";
        int i9 = 0xFFFFFFFF;

        string9 = string5 + i9;
        char char9 = string9.charAt(0);

    }
}

參考: