java基础类型中的char和byte的辨析及Unicode编码和UTF-8的区别

简介: java基础类型中的char和byte的辨析及Unicode编码和UTF-8的区别

在平常工作中使用到char和byte的场景不多,但是如果项目中使用到IO流操作时,则必定会涉及到这两个类型,下面让我们一起来回顾一下这两个类型吧。

char和byte的对比

byte

byte 字节,数据存储容量1byte,byte作为基本数据类型表示的也是一个存储范围上的概念,有别于int、long等专门存数字的类型,这种类型的大小就是1byte,而int是4byte。

存数字的话就是1byte=8位,2^8=256 即-128-127。字符的话包括字母和汉字,一个字母是1byte,一个汉字2byte。也就是可以用byte变量去存储一个英文字符,但是却存不下一个中文汉字,因为一个汉字占2byte。

总结,byte是java中的一个基本数据类型,这个数据类型的长度是1byte,此byte就是彼byte,即是基本数据类型也是存储空间的基本计量单位。

char

char是Java中的保留字,与别的语言不同的是,char在Java中是16位的,因为Java用的是Unicode。不过8位的ASCII码包含在Unicode中,是从0~127的。

Java中使用Unicode的原因是,Java的Applet允许全世界范围内运行,那它就需要一种可以表述人类所有语言的字符编码。Unicode。

char本质上是一个固定占用两个字节的无符号正整数,这个正整数对应于Unicode编号,用于表示那个Unicode编号对应的字符。

由于固定占用两个字节,char只能表示Unicode编号在65536以内的字符,而不能表示超出范围的字符。

Unicode和UTF-8的对比

Unicode

需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字"严"的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题,第一个问题是,如何才能区别Unicode和ASCII?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:1)出现了Unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示Unicode。2)Unicode在很长一段时间内无法推广,直到互联网的出现。

UTF-8

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。

以utf8为例,utf8是一个变长编码标准,可以以1~4个字节表示一个字符,而中文占3个字节,ascII字符占1个字节。

为什么我们在java里面可以用一个char来表示一个中文呢?

因为java是以unicode作为编码方式的。unicode是一个定长的编码标准,每个字符都是2个字节,也就是1个char类型的空间。

在编译时会把utf8的中文字符转换成对应的unicode来进行传输运算。

 

示例代码

package com.lingyejun.io;
import java.io.UnsupportedEncodingException;
/**
 * Created by Lingye on 2018/9/28 14:34
 */
public class ChineseCharCode {
    public static void main(String[] args) {
        String str = "中";
        char c = '中';
        // java使用unicode编码,一个字符占两个字节
        System.out.println("char字符 中 二进制"+Integer.toBinaryString(c));
        try {
            // UTF-8是Unicode的实现方式之一
            System.out.println(str.getBytes("UTF-8").length);
            // UTF-16也是Unicode的实现方式之一,但使用较少
            System.out.println(str.getBytes("UTF-16").length);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

输出结果及总结


  • 因为Java是以unicode作为编码方式的。unicode是一个定长的编码标准,每个字符都是2个字节,也就是1个char类型的空间。
  • Java在编译时会把utf8的中文字符转换成对应的unicode来进行传输运算。
  • 在Java中,基本类型char,固定占两个字节,char本质上就是一个无符号的正整数,我们可以使用Integer.toBinaryString(c))将其打印出来。
  • UTF-8采用的是变长字节编码的方式进行编码,一个汉字可以以1~4个字节表示一个字符,而中文占3个字节,ascII字符占1个字节。

 

参考文章:https://www.zhihu.com/question/23374078


目录
相关文章
|
2月前
|
Java
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
94 4
|
2月前
|
Java
Java实现随机生成某个省某个市的身份证号?如何编码?
【10月更文挑战第18天】Java实现随机生成某个省某个市的身份证号?如何编码?
164 5
|
2月前
|
Java
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
70 2
|
4月前
|
安全 Java API
告别繁琐编码,拥抱Java 8新特性:Stream API与Optional类助你高效编程,成就卓越开发者!
【8月更文挑战第29天】Java 8为开发者引入了多项新特性,其中Stream API和Optional类尤其值得关注。Stream API对集合操作进行了高级抽象,支持声明式的数据处理,避免了显式循环代码的编写;而Optional类则作为非空值的容器,有效减少了空指针异常的风险。通过几个实战示例,我们展示了如何利用Stream API进行过滤与转换操作,以及如何借助Optional类安全地处理可能为null的数据,从而使代码更加简洁和健壮。
129 0
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
91 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
3月前
|
存储 移动开发 Java
java核心之字符串与编码
java核心之字符串与编码
27 2
|
4月前
|
Java PHP 开发者
PHP中的异常处理:Java常见的编码方式
在PHP开发中,掌握异常处理至关重要,它有助于预见并管理运行时错误,避免用户体验受损或数据丢失。本文介绍PHP异常处理的基本概念与实践,包括try-catch语句的使用,以及如何通过抛出和捕获异常来增强代码的健壮性和可靠性。通过示例展示如何避免常见错误,如除数为零的情况,并探讨多catch块和finally语句的高级用法,帮助开发者提升程序稳定性与可维护性。[总字符数:238]
34 0
|
Java
java 读取文件 获取byte[]字节 并执行Gzip的压缩和解压
java 读取文件 获取byte[]字节 并执行Gzip的压缩和解压
125 0
|
5月前
|
Java Apache Maven
Java:commons-codec实现byte数组和16进制字符串转换
在上述代码中,`Hex.encodeHexString(bytes)`用于将byte数组转换为16进制字符串,`Hex.decodeHex(hexString)`用于将16进制字符串转换为byte数组。
111 0
|
5月前
|
Java Apache Maven
Java:commons-codec实现byte数组和16进制字符串转换
在上述代码中,`Hex.encodeHexString(bytes)`用于将byte数组转换为16进制字符串,`Hex.decodeHex(hexString)`用于将16进制字符串转换为byte数组。
133 0