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如图所示:
下面泥瓦匠写个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的十六进制: 1117的八进制: 2117的二进制: 10001171717 |
补充:如果值太大,则需要调用 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 711206010035 |
代码详细解释如下:
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中的进制详解的更多相关文章
- C/C++编程笔记:C语言进制详解,二进制、八进制和十六进制!
我们平时使用的数字都是由 0~9 共十个数字组成的,例如 1.9.10.297.952 等,一个数字最多能表示九,如果要表示十.十一.二十九.一百等,就需要多个数字组合起来. 例如表示 5+8 的结果 ...
- Java并发编程--多线程中的join方法详解
Java Thread中, join()方法主要是让调用该方法的thread在完成run方法里面的部分后, 再执行join()方法后面的代码 例如:定义一个People类,run方法是输出姓名年龄. ...
- Java学习之继承中的执行顺序详解
代码块(理解) (1)用{}括起来的代码. (2)分类: A:局部代码块 用于限定变量的生命周期,及早释放,提高内存利用率. B:构造代码块 把多个构造方法中相同的代码可以放到这里,每个构造方法执行前 ...
- 二进制之Java中的进制(二)
1. jdk中的进制转换 十进制转十六进制 Integer.toHexString(int i); 十进制转八进制 Integer.toOctalString(int i); 十进制转二进制 Inte ...
- java中16进制转换10进制
java中16进制转换10进制 public static void main(String[] args) { String str = "04e1"; String myStr ...
- java中的进制转换
java中的进制转换及转换函数 转自:https://blog.csdn.net/V0218/article/details/74945203 Java的进制转换 进制转换原理 十进制 转 二进制: ...
- java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET
java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET 亲,“社区之星”已经一周岁了! 社区福利快来领取免费参加MDCC大会机会哦 Tag功能介绍—我们 ...
- Java中的main()方法详解
在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
随机推荐
- Python Day 7
阅读目录 内容回顾: 数据类型相互转换: 字符编码: ##内容回顾 #1.深浅拷贝 ls = [1, 'a', [10]] 值拷贝:直接赋值 ls1 = ls, ls中的任何值发生改变,ls1中的值都 ...
- spring学习(二)---依赖注入
spring第二个特性是依赖注入. 学习依赖注入,首先应该明白两个问题:1,谁依赖谁:2,谁注入,注入什么? 首先还是看代码: 还是这个bean: package testSpring.busines ...
- Promise实战AJAX封装
一.利用Promise的知识,对最开始的ajax的例子进行一个简单的封装: var url = 'xxx'; // 封装一个get请求的方法 function request(url){ return ...
- redis学习-列表(list)常用命令
redis学习-列表(list)常用命令 lpush:从列表左侧头部添加数据 rpush:从右侧尾部添加数据 lpop:从给左侧头部取出一个元素 rpop:从右侧尾部取出一个元素 lrange:取 ...
- MyBatis-Plus 3.0.3 Sql注入器添加,即全局配置Sql注入器,sqlInjector改写
官网上写着 但是,这个其实是2.0系列的写法,由于引用了最新的3.0.3这个功能基本不好使. 3.0.3版本的写法 也就是中间加了一层,原来是AutoSqlInjector,现在改为AbstractS ...
- Eclipse的application.properties文件输出中文成unicode编码
今天添application.properties时,无法输入中文,输入的中文直接变成了unicode的编码形式.原因是Eclipse的Spring Properties文件的默认编码为iso-885 ...
- JAVA数据结构之链表
JAVA数据结构之链表 什么是链表呢? 链表作为最基本的数据结构之一,定义如下: 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 简单来说呢,链 ...
- Express实例代码分析1——简单的用户验证登录文件
/** * Module dependencies. */ var express = require('../..');// ../..是上级目录的上级目录 var hash = require(' ...
- Kerberos协议
Kerberos协议主要用于计算机网络的身份鉴别 (authentication),其特点是用户只需输入一次身份验证信息就可以凭借此验证获得票据(ticket-granting-ticket)访问多个 ...
- day_12函数默认值,数据类型的补充,函数对象名称空间与作用域,函数的嵌套定义
复习, 昨天讲了字符串的比较,按照从左往右比较每一个字符,通过字符对应的ASCII码进行比较 函数的参数,‘ 实参与形参 形参:在函数定义时()中出现的参数 实参,在函数调用时()中出现的参数 实参的 ...