Java中的byte/char/String数据类型转换

时间:2021-11-08 15:56:34

前言:项目中遇到了一个问题,Android手机和硬件建立Socket通信,当手机批量发送数据时,发送频率高于单片机接收报文进入中断处理的频率,导致硬件处理不过来。解决的方法是将原先的String类型的大量报文包含的信息,简化成一条十六进制的报文。

在解决完这个问题后,才意识到Java中数据类型转换的重要性,而且Java和C之间的Socket通信最好全部由字节来实现,所以post一篇心得和经验。


一、 字符编码方式及类型转换简介

通常意义上的字符和数字所代表的含义和机器语言是有出入的。对机器而言,“数字”只有代表高低电平的0或1;而无论1~9,a~z,A~Z,汉字,拉丁字母,希腊字母等等,都被视为“字符”。编码,就是将这些“字符”和固定长度的0、1组合唯一对应起来。

常用的编码方式有Unicode、ASCII、UTF-8、GB2312、ISO-8899-1等。采用不同的编码方式,同样的n位二进制“数字”组合代表的“字符”也会不一样。具体采用什么样的编码方式,对“字符”怎样解析,就要看编程所在的平台是什么样了。同时,为了方便,我们并不会直接用n位二进制的“数字”表示,而是用它的十六进制“数字”表示。

在介绍Java平台下的数据类型转换时,本文涉及到了Unicode、ASCII、GB2312、ISO-8899-1,简单说明如下:

  1. Java内核采用Unicode编码,Unicode又称为万国码、统一码,是完全国际化的字符集,可以表示全部人类语言中的字符。

  2. Unicode编码方式是双字节编码,即每个字符=两个字节=16位数,存储范围在\u0000~\uFFFF。表示一个Unicode的字符时,通常会用“\u”然后紧接着一组十六进制的数字来表示这一个字符

  3. 在Java中,有以下八种基本数据类型

    (1) byte、int、short之间不会互相转换,因为容量小的数据类型会自动转换为大的数据类型,所以在运算时,它们都会被转换为int型

    (2)容量大的数据类型转换成容量小的数据类型时,要加上强制转换符,但可能会造成精度降低或数据溢出

    (3)Java中的类型转换总结来说就是 整型-字符型-String 之间的转换

    (4)String不属于Java的基本数据类型,String的本质是字符数组,是类对象

    数据类型 名称 长度 备注
    byte 字节型 1字节 = 8bit 表示数据范围:-128~127
    short 短整型 2字节 = 16bit
    char 字符型 2字节 = 16bit 等价于Unicode编码
    int 整型 4字节 = 32bit
    long 长整型 8字节
    float 单精度浮点型 4字节 精度:7-8位
    double 双精度浮点型 8字节
    boolean 布尔型 true/false

二、 byte\char转换和Unicode编码

  1. 从上面的表中,我们已经知道了char是2字节,byte是1字节,举例说明如下:

    char a=’中’ 合法:在GB2312编码方式中,一个中文字符=2字节
    char a=’ab’ 非法:尽管一个char占用2字节,但是只能表示一个字符
    byte a=’中’ 非法:1字节不能存放中文字符
    byte a=’a’ 合法:一个字符=1字节

  2. 测试Demo:输入Unicode,分别转换成ISO、GB2312、ASCII编码代表的字符

(1) 程序

输入包括:2位byte=1个中文字符;1位byte=1个字符,并通过不同编码方式转码不同成字符


private void Byte2Char() {
// TODO Auto-generated method stub
byte b[] = {(byte)'\u0080',(byte)'\u0001',(byte)'\u007f',(byte)'\u00ff',(byte)'\u00BA',(byte)'\u00CF'};
/**
* 通过ByteToCharConverter类转换不可行,sun.io.*包属于内部API,已经不可用
* ByteToCharConverter converter = ByteToCharConverter.getConverter("gb2312");
* char c[] = converter.convertAll(b);
*/


Charset charSet = Charset.forName("8859_1");
ByteBuffer byteBuffer = ByteBuffer.allocate(b.length);
byteBuffer.put(b);
byteBuffer.flip();
CharBuffer charBuffer = charSet.decode(byteBuffer);

textView1.setText("Byte2Char() 单字节编码 ISO-8899-1"
+"\n"+"目标格式:"+charSet
+"\n"+"输入4字节byte:0080 0001 007f 00ff 00BA 00CF "
+"\n"+"输出Char字符:"+charBuffer
+"\n"+"byte型8位2进制:"+b[0]+"/"+b[1]+"/"+b[2]+"/"+b[3]+"/"+b[4]+"/"+b[5]
);
}

(2)输出

Java中的byte/char/String数据类型转换

注:ISO-8899-1转码时Log有误,“输入4字节byte”应改为“输入6字节byte”


三、 Java中的String类

下面是String源码类注释中的一段话:

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.

同时,String类还使用了final修饰符,下面是String类的成员变量定义:

private final char value[]
private final int count

String的实质就是字符数组,以上内容包含了String的三个特点:
(1)String是值不可变的常量
(2)String是线程安全的
(3)String类是不可继承的


五、 参考资料

[1] http://blog.csdn.net/yutianzuijin/article/details/24807417
作者和我遇到的问题是一样的:Java和C之间建立Socket通信的方案,数据格式不统一是很重要的问题
[1] http://blog.csdn.net/taohuaxinmu123/article/details/12099105
这篇博客详细介绍了Java基本数据类型及转换,基本数据类型的对象包装器
[2]
http://blog.csdn.net/lpali/article/details/5405203
这篇博客清楚的介绍了作者对于“字符”和“数字”,Java和C,Unicode和其它编码方式的理解
[3] http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
这篇文章介绍了Unicode编码,写得很好
[4] http://my.oschina.net/xiaohui249/blog/170013
这篇文章后半部分深入介绍了Java中的String类