作者:李强强

上一篇,泥瓦匠基础地讲了下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如图所示

下面泥瓦匠写个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通信中的数据

下面简单把泥瓦匠学生的故事延续。

如图,库表中一个学生对象,有个属性是学号。这时候客户端要向服务端发送这个对象。过程如下:

1、对象实现Serializable接口。

实现了Serializable接口的对象,可将它们转换成一系列字节,并可在以后完全恢复回原来的样子。

2、其学号属性值 1206010035,由客户端转换为字节码。

3、字节码传输至服务端

4、服务端接收并转换为对象属性值。

五、总结

此文讲的点有点多,泥瓦匠就想把这块用到的知识点串起来,然后慢慢每个讲解。总结如下:

1、Java中进制转换是什么?

2、Java中进制转换的作用?

Writer      :BYSocket(泥沙砖瓦浆木匠)

微         博:BYSocket

豆         瓣:BYSocket

FaceBook:BYSocket

Twitter    :BYSocket

Java I/O : Java中的进制详解的更多相关文章

  1. C/C++编程笔记:C语言进制详解,二进制、八进制和十六进制!

    我们平时使用的数字都是由 0~9 共十个数字组成的,例如 1.9.10.297.952 等,一个数字最多能表示九,如果要表示十.十一.二十九.一百等,就需要多个数字组合起来. 例如表示 5+8 的结果 ...

  2. Java并发编程--多线程中的join方法详解

    Java Thread中, join()方法主要是让调用该方法的thread在完成run方法里面的部分后, 再执行join()方法后面的代码 例如:定义一个People类,run方法是输出姓名年龄. ...

  3. Java学习之继承中的执行顺序详解

    代码块(理解) (1)用{}括起来的代码. (2)分类: A:局部代码块 用于限定变量的生命周期,及早释放,提高内存利用率. B:构造代码块 把多个构造方法中相同的代码可以放到这里,每个构造方法执行前 ...

  4. 二进制之Java中的进制(二)

    1. jdk中的进制转换 十进制转十六进制 Integer.toHexString(int i); 十进制转八进制 Integer.toOctalString(int i); 十进制转二进制 Inte ...

  5. java中16进制转换10进制

    java中16进制转换10进制 public static void main(String[] args) { String str = "04e1"; String myStr ...

  6. java中的进制转换

    java中的进制转换及转换函数 转自:https://blog.csdn.net/V0218/article/details/74945203 Java的进制转换 进制转换原理 十进制 转 二进制: ...

  7. java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET

    java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET 亲,“社区之星”已经一周岁了!      社区福利快来领取免费参加MDCC大会机会哦    Tag功能介绍—我们 ...

  8. Java中的main()方法详解

    在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...

  9. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

随机推荐

  1. [Bat]UNC路径不支持的2种解决方法

    UNC(Universal Naming Convention),\\servername\sharename,其中servername是服务器名.sharename是共享资源的名称 1.使用push ...

  2. P4178 Tree

    最简单的点分治 淀粉质的思想: “分而治之”,缩小问题规模,合并求解: #include<cstdio> #include<cmath> #include<cstring ...

  3. mpdf-html转PDF,中文字符乱码、加粗问题

    $defaultConfig = (new ConfigVariables())->getDefaults(); $fontDirs = $defaultConfig['fontDir']; $ ...

  4. C# MVC验证Model

    .NET Core MVC3 数据模型验证的使用 这里我先粘贴一个已经加了数据验证的实体类PeopleModel,然后一一介绍. using System; using System.Collecti ...

  5. LinkeList 特有方法

    LinkedList:特有方法:addFirst();addLast();添加元素到集合,添加到头尾,getFirst();getLast();获取元素,但不删除元素.如果集合中没有元素,会出现NoS ...

  6. Linux目录/usr结构说明

    在 linux 文件结构中,有一个很神奇的目录 -- /usr. 讨论中,大部分观点认为: usr 是 unix system resources 的缩写: usr 是 user 的缩写: usr 是 ...

  7. Android Stdio的问题

    昨天还是可以运行的,今天运行Android Studio,一直提示:Error running app: Instant Run requires 'Tools | android | Enable ...

  8. redis在linux云服务器上完整的搭建步骤

    Redis的安装 搭建环境: 华为云linux服务器 Linux系统CneterOS-7.3 SSH客户端 Xshell6 安装c语言编译环境软件如下: 安装报错 然后找到了解决方法: 安装kerne ...

  9. ios uibutton加数字角标

    http://www.jianshu.com/p/0c7fae1cadac 第一种:https://github.com/mikeMTOL/UIBarButtonItem-Badge第二种:https ...

  10. 【Solidity】学习(2)

    address 地址类型 40个16进制数,160位 地址包括合约地址和账户地址 payable 合约充值 balance,指的是当前地址的账户value,单位是wei this指的是当前合约的地址 ...