Java I/O : Java中的進制詳解


作者:李強強

上一篇,泥瓦匠基礎地講了下Java I/O : Bit Operation 位運算。這一講,泥瓦匠帶你走進Java中的進制詳解。

 

一、引子

在Java世界里,99%的工作都是處理這高層。那么二進制,字節碼這些會在哪里用到呢?

自問自答:在跨平台的時候,就凸顯神功了。比如說文件讀寫數據通信,還有Java編譯后的字節碼文件。下面會有個數據通信的例子哦。

Java對對象實現Serializablle接口,就可以將其轉化為一系列字節,而在通信中,不必要關系數據如何在不同機器表示和字節的順序。這里泥瓦匠對Serializablle接口,不做詳細講解,以后單獨詳解。

 

二、Java進制轉換

首先認識下Java中的數據類型

1、Int整型:byte(8位,-128~127)、short(16位)、int(32位)、long(64位)

2、Float型:float(32位)、double(64位)

2、char字符:unicode字符(16位)

也就是說,一個int等價於長度為4的字節數組。

Java中進制如何轉換呢?

在Java中,Int整形以及char字符型被包裝的類中提供了一系列的操作方法。比如 java.lang.Integer api如圖所示

QQ截圖20150613210316

下面泥瓦匠寫個demo,驗證下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package javaBasic.oi.byteoper;
 
public class IntegerOper
{
     public static void main(String[] args)
     {
         System.out.println("17的十六進制: " + Integer.toHexString(17));
         System.out.println("17的八進制:     "   + Integer.toOctalString(17));
         System.out.println("17的二進制:     "   + Integer.toBinaryString(17));
 
         System.out.println(Integer.valueOf("11", 16));
         System.out.println(Integer.valueOf("21", 8));
         System.out.println(Integer.valueOf("00010001", 2));
     }
}

右鍵Run一下,我們可以在控制台中看到如下輸出:

?
1
2
3
4
5
6
17的十六進制: 11
17的八進制:   21
17的二進制:   10001
17
17
17

補充:如果值太大,則需要調用 java.lang.Long 提供的方法。

 

三、Java基本類型和字節神奇轉換

這里泥瓦匠想到了自己是個學生,典型的OO思想。那學號:1206010035是整型,怎么轉成字節呢,上面說的擁有字節碼的對象能通信。所以,學校關於學號這個都是這樣的方式通信的。因此,要將學號轉成字節碼才行。

泥瓦匠就寫了個工具類 IntegerConvert.java:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package javaBasic.oi.byteoper;
 
public class IntegerConvert
{
     /**
      * Int轉字節數組
      */
     public static byte[] int2Bytes(int inta)
     {
         // 32位Int可存於長度為4的字節數組
         byte[] bytes = new byte[4];
         for (int i = 0; i <  bytes.length ; i++)
             bytes[i] = (byte)(int)((inta >> i * 8) & 0xff);// 移位和清零
         
         return bytes;
     }
     
     /**
      * 字節數組轉Int
      */
     public static int bytes2Int(byte[] bytes)
     {
         int inta = 0;
         for (int i = 0; i < bytes.length; i++)
             inta += (int)((bytes[i] & 0xff) << i * 8);// 移位和清零
         
         return inta;
     }
     
     public static void main(String[] args)
     {
         // 將我的學號轉換成字節碼
         byte[] bytes = IntegerConvert.int2Bytes(1206010035);
         System.out.println(bytes[0] + " " + bytes[1] + " " + bytes[2] + " " + bytes[3]);
         // 字節碼就可以轉換回學號
         System.out.println(IntegerConvert.bytes2Int(bytes));
     }
 
}

跑一下,右鍵Run,可以看到以下輸出:

?
1
2
-77 64 -30 71
1206010035

代碼詳細解釋如下:

1、(inta >> i * 8) & 0xff

   移位 清零從左往右,按8位獲取1字節

2、這里使用的是小端法。地位字節放在內存低地址端,即該值的起始地址。補充:32位中分大端模式(PPC)和小段端模式(x86)。

 

自然,Long也有其轉換方法,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class LongConvert
{
     /**
      * long 轉 byte數組
      */
     public static byte[] long2Bytes(long longa)
     {
         byte[] bytes = new byte[8];
         for (int i = 0; i <  bytes.length ; i++)
             bytes[i] = (byte)(long)(((longa) >> i * 8) & 0xff); // 移位和清零
         
         return bytes;
     }
     
     /**
      * byte數組 轉 long
      */
     public static long bytes2Long(byte[] bytes)
     {
         long longa = 0;
         for (int i = 0; i < bytes.length; i++)
             longa += (long)((bytes[i] & 0xff) << i * 8); // 移位和清零
         
         return longa;
     }
     
}

 

那字符串,字符數組呢?比如泥瓦匠的名字:李強強

Java也提供了一系列的方法,其實 java.lang.String 封裝了char[],其中本質還是對char數組的操作。代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package javaBasic.oi.byteoper;
 
public class StringConvert
{
     public static void main(String[] args)
     {
         String str = "李強強";
         byte[] bytes = str.getBytes();
         // 打印字節數組
         System.out.println("'李強強'的字節數組為:");
         for (int i = 0; i < bytes.length; i++)
             System.out.print("\t" + bytes[i]);
     }
}

右鍵Run一下,可以看到以下輸出:

?
1
2
'李強強'的字節數組為:
     -64 -18 -57 -65 -57 -65

論證:這里我們論證了一個中文,需要兩個字節表示,也就是說一個中文是16位

 

四、淺談Java通信中的數據

下面簡單把泥瓦匠學生的故事延續。socket

如圖,庫表中一個學生對象,有個屬性是學號。這時候客戶端要向服務端發送這個對象。過程如下:

1、對象實現Serializable接口。

實現了Serializable接口的對象,可將它們轉換成一系列字節,並可在以后完全恢復回原來的樣子。

2、其學號屬性值 1206010035,由客戶端轉換為字節碼。

3、字節碼傳輸至服務端

4、服務端接收並轉換為對象屬性值。

 

五、總結

此文講的點有點多,泥瓦匠就想把這塊用到的知識點串起來,然后慢慢每個講解。總結如下:

1、Java中進制轉換是什么?

2、Java中進制轉換的作用?

 

 

 

Writer      :BYSocket(泥沙磚瓦漿木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM