zoukankan      html  css  js  c++  java
  • 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(" " + 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

  • 相关阅读:
    cmanformat
    mysql-sql语言参考
    jQuery 判断多个 input checkbox 中至少有一个勾选
    Java实现 蓝桥杯 算法提高 计算行列式
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
  • 原文地址:https://www.cnblogs.com/Alandre/p/4574842.html
Copyright © 2011-2022 走看看