文档章节

Java I/O : Java中的进制详解

泥瓦匠BYSocket
 泥瓦匠BYSocket
发布于 2015/06/14 11:40
字数 1272
阅读 449
收藏 22

作者:李强强

上一篇,泥瓦匠基础地讲了下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,验证下。

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一下,我们可以在控制台中看到如下输出:

17的十六进制: 11
17的八进制:   21
17的二进制:   10001
17
17
17


补充:如果值太大,则需要调用 java.lang.Long 提供的方法。

三、Java基本类型和字节神奇转换

这里泥瓦匠想到了自己是个学生,典型的OO思想。那学号:1206010035是整型,怎么转成字节呢,上面说的拥有字节码的对象能通信。所以,学校关于学号这个都是这样的方式通信的。因此,要将学号转成字节码才行。

泥瓦匠就写了个工具类 IntegerConvert.java

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,可以看到以下输出:

-77 64 -30 71
1206010035
 

代码详细解释如下:

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

   移位 清零从左往右,按8位获取1字节

2、这里使用的是小端法。地位字节放在内存低地址端,即该值的起始地址。补充:32位中分大端模式(PPC)和小段端模式(x86)。


自然,Long也有其转换方法,如下:

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数组的操作。代码如下:

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

© 著作权归作者所有

泥瓦匠BYSocket

泥瓦匠BYSocket

粉丝 951
博文 174
码字总数 229265
作品 4
杭州
程序员
私信 提问
Java程序员进化为架构师需要掌握的知识

Java程序员进化为架构师掌握的知识: 一:Java知识 1、进制转换 2、Java基本数据类型 面向对象相关知识 3、类、接口、抽象类 this关键字、static关键字、final关键字 方法的参数传递机制 Ja...

andogo
2014/05/16
1K
2
Java程序员从笨鸟到菜鸟全部博客目录【2012年十一月七日更新】

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,...

长平狐
2012/11/12
212
0
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
2018/06/21
0
0
《Java程序员由笨鸟到菜鸟》电子版书正式发布,欢迎大家下载

在众多朋友的支持和鼓励下,《Java程序员由菜鸟到笨鸟》电子版终于和大家见面了。本电子书涵盖了从java基础到javaweb开放框架的大部分内容。在编写的过程中,难免会出现一些错误,希望大家能...

长平狐
2012/11/12
255
0
《Java程序员由笨鸟到菜鸟》电子版书正式发布,欢迎大家下载

在众多朋友的支持和鼓励下,《Java程序员由菜鸟到笨鸟》电子版终于和大家见面了。本电子书涵盖了从java基础到javaweb开放框架的大部分内容。在编写的过程中,难免会出现一些错误,希望大家能...

长平狐
2012/11/12
144
0

没有更多内容

加载失败,请刷新页面

加载更多

使用QRCode.js生成二维码

什么是 QRCode.js? QRCode.js 是一个用于生成二维码的 JavaScript 库。主要是通过获取 DOM 的标签,再通过 HTML5 Canvas 绘制而成,不依赖任何库。 基本用法 <div id="qrcode"></div><scrip......

前端老手
18分钟前
5
0
spring-web 目录结构

ls /opt/pkg/spring-framework/spring-web/src/main/java/org/springframework/web/accept cors HttpMediaTypeNotSupportedException.java j......

MtrS
32分钟前
3
0
Qt编写自定义控件55-手机通讯录

一、前言 前面几篇文章中的控件基本上难度系数接近0,甚至有凑控件数量的嫌疑,这次必须来一个强悍的控件,本控件难度系数在所有控件中排前五,代码量也不少,头文件都550行,实现文件1600行...

飞扬青云
48分钟前
29
0
C++与QML交互2:在QML中调用C++特性

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/xi_gua_gua/article/details/56991367 QML引擎(QQmlEngin...

shzwork
今天
3
0
【Go专家编程】defer这里有个坑

前言 项目中,有时为了让程序更健壮,也即不panic,我们或许会使用recover()来接收异常并处理。 比如以下代码: func NoPanic() {if err := recover(); err != nil {fmt.Println("Recov...

恋恋美食
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部