由char和byte的关系引申出去——总结一下java中的字符编码相关知识

一、字符编码

手持两把锟斤拷,口中直呼烫烫烫

​   在文章伊始,先来复习一下计算机中关于编码的一些基础知识,着重理清以下几个基本概念。

1. 码点(code point)

​   计算机只能以二进制的形式存储文字,故而计算机中每一个字母,文字,符号,emoji都对应着一个二进制数,而这个二进制数就是码点

2. 字符集

​   光有码点还不够,我们还得知道有哪些码点,这些码点又能表示哪些字符,于是便又到了喜闻乐见的制定标准环节。标准所支持的所有字符及其对应码点的集合被称为字符集。例如学过C语言的同学都知道的ASCII字符集,它共包含了128个字符,包括数字,26个字母的大小写及一些符号,对应的码点就是0-127。再有就是后面要提到的Unicode字符集。

3. 编码

​   以ASCII字符集为例,它的码点为0-127,最大不超过7bit,而计算机中一般是以8bit的字节(byte)为单位。出于种种考量,实际存储在计算机中的码点的二进制都会在头部添0,以8bit存储。例如A对应码点65,二进制为100 0001,实际在计算机中存储为0100 0001。这种在计算机中实际存储的内容到字符的映射就是编码。

​   我们熟悉的编码方式有ASCII,UTF-8,UTF-16,欧洲的ISO,中国大陆的GBK等等。计算机中存储的同一段二进制,用不同的编码方式,会得到完全不同的内容。

4. Unicode字符集

​   ASCII一共只包含了128个字符,显然不够用,于是便有了Unicode字符集。Unicode字符集中收录了世界上绝大多数文字,符号等,反正就是非常多。

​   行文至此,笔者想到自己当初学习时的一个疑惑,即字符集已经规定好了字符到码点的映射,为啥还有各种不同的编码方式。如果读者仔细理解了上文不难发现,在计算机中以何种方式存储码点是需要编码来确定。最简单的方法就是直接将码点转成二进制存储,比如对ASCII字符集的ASCII编码,对Unicode的UTF-32编码。

​   由于Unicode字符集数量极其旁大,单个字符最大已超过了3个字节(具体多大我也不清楚,目前用4个字节还足够表示),同时为了区分前后两个字符在哪里断开,utf-32编码简单粗暴得将每个字符以32位4字节的形式存储在计算机中。这样很好理解,但带来了严重的空间浪费,对于常用的字母得要存一堆0,简直就是0溢事件。

5. UTF-8编码

​   我们常见的utf-8便是为了解决上述问题而诞生的,他是针对于Unicode的可变长度编码方式,可以把不同字符以1,2,3,4字节大小存储到计算机中,同时utf-8兼容ascii,具体规则参考下图,也推荐大家看一下图片下方链接的视频,讲的很好:

图片来源:【你懂乱码吗?锟斤拷烫烫烫(详解ASCII、Unicode、UTF-32、UTF-8编码)】 https://www.bilibili.com/video/BV1xP4y1J7CS/?share_source=copy_web&vd_source=f5db843fce15b7c3e2990f4f7a6e8921

二、Java中的字符编码

1. 编码方式:

​   有了以上知识的铺垫,其实接下来的问题就很好解决了。

​   首先,java中采用的是基于Unicode字符集的UTF-16编码方式。utf-16可以将不同字符以2或4字节大小存储在计算机中,可能有同学已经发现规律了,utf-8是以8bit为最小单位,而utf-16是以16 bit为最小单位,而这个最小单位实际上就是所谓的代码单元(code unit)

2. char类型:

​   基本类型char类型就是一个16bit的代码单元。我们日常里常用的字符,如字母,汉字等只需要一个char,而对于一些类似于emoji这样的码点值很大的字符,需要两个char。

​   java中char类型的字面量用'A'单引号括起来,表示一个字符常量。对于一些特殊字符,如回车,换行,我们要用到转义字符来表示,如下图:

图片来源:《java核心技术卷Ⅰ》

3. 应用:

​   行文至此,笔者又想起之前曾经看到过的一个相关的案例。

​   简言之就是需要对数据库中取出的用户名做一个截断,比如某些情况下只需要呈现用户名的前三个字。而这个系统允许用户上传的用户名中包含emoji表情。

​   在这种情况下就要注意了,一个emoji字符由两个char组成,如果简单得用String.subString()或者String.length是有问题的,因为这些方法都是以char为单位,可能会造成把一个emoji字符只截了一个char出来,从而导致问题。在这里就需要用String的codePoint相关的方法去截取,以码点为单位,因为一个码点一定代表一个字符,而一个char则未必。

​   详情见该视频:【Emoji 表情导致线上故障2个小时。老板直接损失10万。到底是什么问题?| 故障复盘 | 实战经验分享】 https://www.bilibili.com/video/BV1MG41177pT/?share_source=copy_web

三、 总结:

​   如果您坚持看到了这里,那么我想一定已经对于我标题提出的问题的答案了然于胸了。

​   char和byte的关系,现在看来这俩也没啥关系嘛,只能说我这个引申不是很合适。本文着重介绍了计算机字符编码的相关知识,同时也总结了java中有关字符编码的一些内容,希望能对你有所帮助。

四、 参考资料:

  1. 【你懂乱码吗?锟斤拷烫烫烫(详解ASCII、Unicode、UTF-32、UTF-8编码)】 https://www.bilibili.com/video/BV1xP4y1J7CS/?share_source=copy_web&vd_source=f5db843fce15b7c3e2990f4f7a6e8921
  2. 《java核心技术卷Ⅰ》

鄙人只是一名在读的软件工程专业的本科生,正在复习找工作,故而将复习时遇到的一些有意思的东西总结出来,既是加深理解,也是便于日后复习。

鄙人才疏学浅,若文中有谬误之处,还望诸位不吝斧正,以免误人子弟。若有同道中人想一同讨论学习,也可以联系我=>2938189276@qq.com。未经本人同意,请勿转载!

路漫漫其修远兮,吾将上下而求索。

由char和byte的关系引申出去——总结一下java中的字符编码相关知识的更多相关文章

  1. 字符编码:Unicode和UTF-8之间的关系

    Unicode和UTF-8之间的关系 1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256 ...

  2. java 中String编码和byte 解码总结——字节流和字符流

    1.InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符 InputStreamReader(InputStream in, Strin ...

  3. 字符编码:Unicode和UTF-8的关系

    今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问题比我想象的复杂,从午饭后一直看到晚上9点,才算初步搞清楚. 下面就是我的笔记,主要用来整理自己的思 ...

  4. .NET和JAVA中BYTE的区别以及JAVA中“DES/CBC/PKCS5PADDING” 加密解密在.NET中的实现

    场景:java 作为客户端调用已有的一个.net写的server的webservice,输入string,返回字节数组. 问题:返回的值不是自己想要的,跟.net客户端直接调用总是有差距 分析:平台不 ...

  5. c#与java中byte字节的区别及转换方法

    原文:c#与java中byte字节的区别及转换方法 在java中  byte的范围在 [-128,127] 在C#中  byte的范围在 [0,255] 所以 java程序与C#程序 进行数据传输的时 ...

  6. java中的byte有什么作用?

    byte即字节的意思,是java中的基本类型,用心申明字节型的变量. 通常在读取非文本文件时(如图片,声音,可执行文件)需要用字节数组来保存文件的内容,在下载文件时,也是用byte数组作临时的缓冲器接 ...

  7. 为什么 char 数组比 Java 中的 String 更适合存储密码?

    另一个基于 String 的棘手 Java 问题,相信我只有很少的 Java 程序员可以正确回答这个问题.这是一个真正艰难的核心Java面试问题,并且需要对 String 的扎实知识才能回答这个问题. ...

  8. 计算机基础--Java中int char byte的关系

    计算机基础--Java中int char byte的关系 重要:一个汉字占用2byte,Java中用char(0-65535 Unicode16)型字符来存字(直接打印输出的话是字而非数字),当然要用 ...

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

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

  10. 从源码和doc揭秘——Java中的Char究竟几个字节,Java与Unicode的关系

    #编码与字符编码 (懂编码的建议直接跳过) 在计算机世界中,任何事物都是用二进制图片数字表示的,图片可以编码为JPG,PNG格式的字节流,音频,视频有MP3,MP4格式的字节流.这些JPG,MP3等都 ...

随机推荐

  1. JetBrains Fleet初体验,如何运行一个java项目

    序言 各位好啊,我是会编程的蜗牛,JetBrains 日前宣布其打造的下一代 IDE Fleet 正式推出公共预览版,现已开放下载.作为java开发者,对于JetBrains开发的全家桶可以说是印象深 ...

  2. v-for和router-link的共同使用

    1. 错误例子 <div style="color: red" v-for="item in pressionList" :key="item. ...

  3. 2.签名&初始化&提交

      Git设置签名 签名的作用是区分不同操作者的身份,用户的签名信息在每一个版本的提交信息中能够看到, 以此确认本次提交是谁做的,git首次安装必须设置用户签名,否则无法提交代码 这里设置的用户签名和 ...

  4. vue3+element-plus+登录逻辑token+环境搭建

    vue3+element-plus+登录逻辑token环境搭建 安装脚手架工具 1 npm i @vue/cli@4.5.13 -g 验证是否安装成功 1 vue -V # 输出 @vue/cli 4 ...

  5. 十五、资源控制之Deployment

    资源控制器之Deployment Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationControlle ...

  6. JVM学习笔记——垃圾回收篇

    JVM学习笔记--垃圾回收篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的垃圾回收部分 我们会分为以下几部分进行介绍: 判断垃圾回收对象 垃圾回收算法 分代垃圾回收 垃圾回收器 ...

  7. Spring Boot 中使用 Swagger

    前后端分离开发,后端需要编写接⼝说明⽂档,会耗费⽐较多的时间. swagger 是⼀个⽤于⽣成服务器接⼝的规范性⽂档,并且能够对接⼝进⾏测试的⼯具. 作用 ⽣成接⼝说明⽂档 对接⼝进⾏测试 使用步骤 ...

  8. JVM学习笔记——类加载和字节码技术篇

    JVM学习笔记--类加载和字节码技术篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的类加载和字节码技术部分 我们会分为以下几部分进行介绍: 类文件结构 字节码指令 编译期处理 类 ...

  9. java判断手机号三大运营商归属的工具类

    package com.tymk.front.third; import java.util.regex.Pattern; public class OperatorsUtil { /** * 中国电 ...

  10. win10系统VMWare16 Pro 安装CentOS8

    目录 一.本机环境与问题解决 二.下载软件 三.VMWare16 Pro安装 四.CentOS8 安装 一.本机环境与问题解决 装了好几遍,感觉坑都踩了一遍,泪奔~,还好终于跑起来了! 查看电脑是否开 ...