当前位置: 首页 > article >正文

【Java】UTF-8变长编码及其3字节存储奥秘

UTF-8 是一种变长编码一个字符可能由 1 到 4 个字节组成。解码时将字节数组转回 String计算机并不需要“猜”或者去查表因为长度信息本身就包含在字节的“头部”里。这就是 UTF-8 设计的精妙之处它是“自同步”的。核心机制看字节的“高位”标志计算机读取字节时是按比特Bit一位一位看的。UTF-8 规定利用每个字节的前几位高位来告诉解码器“这个字节是独立字符还是某个字符的一部分”。这就好比我们看车牌号如果第一个字母是“京”我们就知道这车是北京的如果第一个字母是“豫”就知道是河南的。UTF-8 的字节也是通过“长相”来区分的。具体的编码规则表让我们看看一个字节8个比特的二进制表示。x代表存储数据的位0和1是标志位字节数格式说明数据位数量理论最大十进制数实际 UNICODE 上限1 字节0xxxxxxx0开头这是 ASCII 字符0-1277 位1271272 字节110xxxxx 10xxxxxx110开头后面跟 1 个字节11 位2,0472,0473 字节1110xxxx 10xxxxxx 10xxxxxx1110开头后面跟 2 个字节16 位65,53565,5354 字节11110xxx 10.. 10.. 10..11110开头后面跟 3 个字节21 位2,097,1511,114,111⚠️特别注意Unicode 标准的限制虽然 UTF-8 的 4 字节编码规则允许存到 2,097,151但实际上Unicode 标准本身并没有用完这个空间。Unicode 标准目前规定的最大码点是 1,114,111十六进制0x10FFFF。原因为了保持与 UTF-16 等其他编码的兼容性Unicode 标准限定了范围。结论在现实世界的计算机系统中有效的 UTF-8 4 字节字符最大只能到 1,114111。超过这个数值的二进制组合即使符合 UTF-8 的 4 字节格式被认为是“非法码点”不会被标准系统使用。解码器是如何工作的举个例子汉字“中”汉字“中”的 Unicode 码点是U4E2D在 UTF-8 中它需要 3 个字节来存储字节数组[228, 184, 173]十六进制0xE4 0xB8 0xAD解码流程读取0xE411100100看到1110判决这是 3 字节头往后读 2 个。读取0xB810111000看到10判决是第 1 个后续字节继续。读取0xAD10101101看到10判决是第 2 个后续字节。结束凑齐了 3 个字节成功解析出“中”字。解码器看到1110...就知道往后数 2 个字节把这三个字节里的x部分拼在一起就还原出了“中”字。总结解码过程之所以准确是因为 UTF-8 利用了二进制的高位作为标志位如果读到一个字节首位是0→ 1 字符1 字节。如果读到一个字节首位是110→ 1 字符2 字节。如果读到一个字节首位是1110→ 1 字符3 字节。如果读到一个字节首位是10→ 这不是头这是尾巴跟随字节。这种设计非常巧妙既兼容了古老的 ASCII英文只用 1 个字节首位为 0又支持了全世界所有的字符用变长字节而且解码速度快不需要额外的索引表。UTF-83字节存储原理举例汉字“中”的 Unicode 码点是U4E2D十进制20013在 UTF-8 中它需要 3 个字节来存储字节数组[228, 184, 173]十六进制0xE4 0xB8 0xAD。在 Java 内部char类型是使用 2 个字节UTF-16 编码来存储“中”这个字的。但是UTF-8 之所以需要 3 个字节是因为 UTF-8 的编码规则为了兼顾兼容性和可读性牺牲了一定的存储空间。下面详细解释为什么明明 2 个字节够用UTF-8 却非要用 3 个字节。1.数值上的可行性2 字节确实够“中”字的 Unicode 码点是20013十进制。我们把它转换成二进制20013 0100 1110 0010 1101这串二进制一共有 15 位。而 2 个字节等于 16 位。因为 15 16所以单纯存这个数字2 个字节绰绰有余。Java 内部存储UTF-16直接把这 15 位二进制填入 2 个字节中高位补 0即0x4E2D。这就是为什么 Java 的char只需要 2 个字节。2.为什么 UTF-8 需要 3 个字节UTF-8 是一种变长编码。它的设计目标之一是兼容 ASCII 码0-127并且不需要像 UTF-16 那样面临“字节序”大端小端的问题。为了实现这一点UTF-8 规定了非常严格的位格式。它不像 UTF-16 那样直接把数字填进去而是把二进制位“拆分”到不同的字节容器里每个字节都要留出几位作为“位标记”告诉计算机这个字节是几字节序列的一部分。UTF-8 的位规则1 字节0 - 127格式0xxxxxxx最高位是 0剩下 7 位存数据。2 字节128 - 2047格式110xxxxx 10xxxxxx。第一个字节的前 3 位必须是110。后续字节的前 2 位必须是10。剩下的位才是存数据的5 6 11 位。2 字节 UTF-8 能存的最大数值是 2¹¹ - 1 2047。3 字节2048 - 65535格式1110xxxx 10xxxxxxx 10xxxxxx。第一个字节的前 4 位1110。后续字节的前 2 位10。剩下的位存数据4 6 6 16位。3 字节 UTF-8 能存的最大数值是 2¹⁶ - 1 65535。关键点来了“中”字的数值是 20013。而 2 字节 UTF-8 能存储的最大数值只有 2047。因为20013 2047所以“中”字装不进 2 字节的 UTF-8 格式里必须升级到 3 字节的格式。3.实际转换演示“中”字在 UTF-8 里具体是怎么变成 3 个字节的原始数据二进制0100 1110 0010 1101共 15 位目标模板3字节 UTF-81110xxxx 10xxxxxx 10xxxxxx填充过程从原始数据的低位开始依次填入模板的x中从后往前填取最后 6 位101101→ 填入第 3 个字节 →101011010xAD再取中间 6 位111000→ 填入第 2 个字节 →101110000xB8剩下的高位0100→ 填入第 1 个字节 →111001000xE4最终结果11100100 10111000 10101101即十六进制的E4 B8 AD这就是为什么“中”字在 UTF-8 中占据了 3 个字节。4.总结编码方式存储机制“中”字占用大小原因UTF-16Java char定长大部分直接存储数值2 字节数值 20013 小于 65535直接存入 16 位空间。UTF-8变长需要前缀位标记3 字节UTF-8 的 2 字节模式最大只能存 2047。为了容纳 20013必须用 3 字节模式。一句话概括虽然 2 个字节的盒子容量足够装下 20013 这个数字但 UTF-8 的 2 字节格式包装方式太小了只能装到 2047所以被迫换用了更大的 3 字节包装。

相关文章:

【Java】UTF-8变长编码及其3字节存储奥秘

UTF-8 是一种变长编码,一个字符可能由 1 到 4 个字节组成。 解码时(将字节数组转回 String),计算机并不需要“猜”或者去查表,因为长度信息本身就包含在字节的“头部”里。这就是 UTF-8 设计的精妙之处:它是…...

OpenClaw进阶:利用GLM-4.7-Flash实现复杂任务链式执行

OpenClaw进阶:利用GLM-4.7-Flash实现复杂任务链式执行 1. 为什么需要链式任务执行 上周我在整理项目文档时,遇到了一个典型的多步骤任务:需要从十几个Markdown文件中提取关键数据,整理成Excel表格,然后根据内容生成分…...

知识图谱项目实战(基础概念以及工具使用)【第一章】

在RAG以及Agent的应用领域中,知识图谱可以增强知识库的检索效果(通过搭建知识图谱数据库(GraphRag)实现).在教育医疗以及金融领域应用广泛.图谱(graph)有节点和边组成一.知识图谱理论1.1知识图谱的整体架构1.2知识图谱架构实现流程1. 文本标注(Doccano标…...

Elasticsearch踩坑记录:scaled_float字段查询结果和你想的不一样?

Elasticsearch中的scaled_float:为什么你的查询结果总是不准确? 刚接触Elasticsearch的开发者经常会遇到一个令人困惑的现象:明明存储的是精确的浮点数,查询时却返回了意料之外的结果。这背后往往与scaled_float字段类型的特殊处理…...

经典位运算和计算各进制下的各位数字之和

(num & (num - 1)) 是检测2的幂的经典位运算方法,结果为0即为2的幂 if ((num & (num - 1)) ! 0) 按位与: 0 & 0 0 0 & 1 0 1 & 0 0 1 & 1 1 全 1 才 1,有 0 则 0 int lowbit(int x) { …...

无代码爬虫方案:OpenClaw调度Qwen3.5-9B解析动态网页数据

无代码爬虫方案:OpenClaw调度Qwen3.5-9B解析动态网页数据 1. 为什么需要无代码爬虫? 作为一个经常需要从网页抓取数据的技术博主,我经历过太多抓取数据的痛苦时刻。传统爬虫开发需要处理反爬机制、解析动态加载内容、维护复杂的XPath或CSS选…...

文艺复兴,什么是XSS,常见形式(二)

前言 本文将继续介绍XSS的常见形状,依赖于portswigger提供的免费Lab环境,将重点介绍关于使用脚本来进行表单XSS验证以及针对标签的模糊测试。 Lab: Stored DOM XSS 这是一个存储型的DOM类的XSS,具体的是当你将内容提交到评论区&#xff0c…...

链表合并不解之处

我在做一元多次的方程合并时,在节点函数中定义系数和指数,相当于给你两个La,Lb链表,按照节点中的指数大小排序,对他们系数进行合并。我有两种方式进行编写。题目:第一行包含一个整数 nn,表示第一…...

ViGEmBus如何解决Windows游戏控制器兼容性难题?

ViGEmBus如何解决Windows游戏控制器兼容性难题? 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus ViGEmBus是一款专业的Windows内核模式驱动程序&a…...

包装器简介

可调用对象:可以使用()运算符进行调用的对象,本质是能像函数一样使用的东西常见课调用对象:函数指针,仿函数,lambda表达式我们能否使用统一的方式对其封装,进行调用,这时…...

如何实现精准歌词同步?KRC格式全解析与应用实践

如何实现精准歌词同步?KRC格式全解析与应用实践 【免费下载链接】KuGouMusicApi 酷狗音乐 Node.js API service 项目地址: https://gitcode.com/gh_mirrors/ku/KuGouMusicApi 在音乐应用开发中,歌词显示功能看似简单,实则隐藏着诸多技…...

OpenClaw任务编排:用Qwen3.5-4B-Claude实现爬虫+分析闭环

OpenClaw任务编排:用Qwen3.5-4B-Claude实现爬虫分析闭环 1. 为什么需要自动化任务编排 去年我接手了一个市场调研项目,需要每周从20多个网站抓取产品价格数据,清洗后生成趋势图表。最初用Python脚本手动Excel处理,每次要花3小时…...

大模型进阶必看:Agent Skills如何让AI开发更标准化、可复用?速收藏!

随着AI应用开发成熟,工具调用经历了Function Calling、MCP协议到Agent Skills三个阶段。Agent Skills通过文件系统原生设计,将指令、工作流和资源打包成可复用模块,革新上下文管理,实现代码即工具,摆脱供应商锁定。它使…...

6种压缩黑科技如何彻底解决文件处理的效率难题

6种压缩黑科技如何彻底解决文件处理的效率难题 【免费下载链接】7-Zip-zstd 7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard 项目地址: https://gitcode.com/gh_mirrors/7z/7-Zip-zstd 为何压缩工具总是陷入"速度与压缩率"的两难…...

X-TRACK二次开发终极指南:如何基于开源框架快速扩展新功能

X-TRACK二次开发终极指南:如何基于开源框架快速扩展新功能 【免费下载链接】X-TRACK A GPS bicycle speedometer that supports offline maps and track recording 项目地址: https://gitcode.com/gh_mirrors/xt/X-TRACK X-TRACK是一款支持离线地图和轨迹记…...

OpenClaw+GLM-4.7-Flash学习助手:自动整理课程笔记与生成复习题

OpenClawGLM-4.7-Flash学习助手:自动整理课程笔记与生成复习题 1. 为什么需要自动化学习助手? 去年备考研究生时,我每天要处理3-4小时的课程视频。最痛苦的不是听课本身,而是课后整理:手动截取关键片段、转录字幕、标…...

突破语言边界:XUnity.AutoTranslator全场景应用指南

突破语言边界:XUnity.AutoTranslator全场景应用指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 当你打开一款期待已久的外文游戏,却被满屏陌生文字阻挡了探索的脚步&#xff1…...

探索AI原生应用领域向量数据库的无限潜力

探索AI原生应用领域向量数据库的无限潜力关键词:向量数据库、AI原生应用、Embedding、向量相似度、多模态检索、大模型协同、语义理解摘要:当AI从“辅助工具”进化为“原生生产力”,一种专为AI设计的数据库——向量数据库,正在重塑…...

嵌入式GUI技术选型与实现方案对比

1. 主流小型嵌入式GUI技术解析1.1 TouchGFX技术方案TouchGFX以其华丽的界面效果和流畅的动画著称,采用C语言开发,特别适合STM32系列MCU。其核心优势在于TouchGFX Designer工具,该工具提供:可视化界面设计环境丰富的控件库&#xf…...

大数据产品实战:用户画像系统的设计与实现

大数据产品实战:用户画像系统的设计与实现 关键词:用户画像、标签体系、大数据平台、精准营销、数据挖掘 摘要:用户画像系统是大数据时代企业实现“以用户为中心”运营的核心工具,它通过给用户“贴标签”的方式,将复杂的用户行为转化为可量化、可分析的数字特征。本文将从…...

拒了一个只要1.8万的45岁大佬

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享点击关注#互联网架构师公众号,领取架构师全套资料 都在这里0、2T架构师学习资料干货分上一篇:2T架构师学习资料干货分享大家好,我是互联网架构师&#xff…...

为什么你的Ping总是丢包?这7个隐藏原因90%的人都忽略了(含Wireshark分析技巧)

为什么你的Ping总是丢包?这7个隐藏原因90%的人都忽略了(含Wireshark分析技巧) 在网络运维的日常工作中,Ping命令就像网络工程师的听诊器,简单却至关重要。但当你发现Ping测试频繁丢包时,问题往往不像表面看…...

想给西安碑林、雁塔等区旧房装修?知名靠谱装修公司在哪找?

在西安碑林、雁塔等区拥有一套旧房,想要进行装修,却不知道如何找到知名靠谱的装修公司?别担心,本文将为你详细介绍选择装修公司的方法,并重点推荐西安王师傅装修工程有限公司,为你的旧房装修之旅提供可靠的…...

Spring Boot 中 Quartz 与 PostgreSQL 持久化实战:构建可视化定时任务管理平台

1. 为什么需要定时任务持久化 在企业级应用开发中,定时任务就像是一个不知疲倦的闹钟,每天准时叫醒你的业务逻辑。但传统的Scheduled注解方式有个致命缺陷——所有的任务配置都硬编码在代码里。想象一下,每次修改任务执行时间都需要重新部署应…...

OpenClaw跨平台实战:Windows到Mac的Qwen3-32B配置迁移

OpenClaw跨平台实战:Windows到Mac的Qwen3-32B配置迁移 1. 为什么需要跨平台配置迁移? 去年冬天,我在Windows工作站上搭建了一套基于Qwen3-32B的OpenClaw自动化系统,用于处理日常的文档整理和数据分析任务。当公司配发新款MacBoo…...

Python多进程+ZeroMQ+内存映射=真无锁?资深架构师用17个生产事故告诉你为什么92%的“去GIL”方案在高并发下静默失败

第一章:Python无锁GIL环境下的并发模型避坑指南Python 的全局解释器锁(GIL)长期被误认为是“无锁”环境,实则恰恰相反——GIL 是 CPython 解释器中一把严格的互斥锁,它确保任意时刻仅有一个线程执行 Python 字节码。所…...

智能记账本:OpenClaw+Qwen3.5-9B自动归类信用卡消费邮件

智能记账本:OpenClawQwen3.5-9B自动归类信用卡消费邮件 1. 为什么需要自动化记账工具 每次收到银行消费短信时,我都会陷入两难:手动记账太繁琐,不记账又会导致月度消费分析失真。传统记账软件需要手动输入金额和分类&#xff0c…...

Mojo+Python混合项目部署失败全记录(含完整错误日志溯源与跨运行时调试手册)

第一章:MojoPython混合项目部署失败全记录(含完整错误日志溯源与跨运行时调试手册)在将 Mojo 模块嵌入 Python 3.11 环境的 CI/CD 流水线中,首次构建即触发运行时崩溃。核心现象为 mojo_runtime_init() 在 Python 进程内调用后立即…...

告别频繁输密码!域环境下Windows软件静默安装的两种野路子(慎用)

告别频繁输密码!域环境下Windows软件静默安装的两种野路子(慎用) 在中小企业IT运维的日常中,软件批量部署和远程协助安装堪称两大高频痛点。想象这样的场景:财务部急需更新报税软件,二十台电脑需要同时处理…...

OpenClaw技能市场指南:Qwen3.5-4B-Claude适配的20个实用模块

OpenClaw技能市场指南:Qwen3.5-4B-Claude适配的20个实用模块 1. 为什么需要关注技能市场? 第一次接触OpenClaw时,我以为它只是个能执行简单命令的自动化工具。直到在ClawHub技能市场里发现"会议纪要生成器"模块,才意识…...