Java I/O : Java中的进制详解
  TEZNKK3IfmPf 2023年11月15日 47 0

一、引子

在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,验证下。

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

'李强强'的字节数组为:
	-64	-18	-57	-65	-57	-65

论证 :这里我们论证了一个中文,需要两个字节表示,也就是说 一个中文是16位

四、浅谈Java通信中的数据

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

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

1、对象实现Serializable接口。

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

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

3、字节码传输至服务端

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

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月15日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2023年11月15日   54   0   0 java在线
  TEZNKK3IfmPf   2023年11月15日   25   0   0 java在线
  TEZNKK3IfmPf   2023年11月15日   22   0   0 java在线
  TEZNKK3IfmPf   2023年11月15日   27   0   0 java在线
  TEZNKK3IfmPf   2023年11月15日   26   0   0 java在线
  TEZNKK3IfmPf   2023年11月15日   28   0   0 API数据接口java在线
  TEZNKK3IfmPf   2023年11月15日   31   0   0 java在线
  TEZNKK3IfmPf   2023年11月15日   62   0   0 java在线
TEZNKK3IfmPf