Java char类型介绍

news2024/11/18 22:31:48

前言:最近,想写一篇关于介绍产生”乱码问题“根本原因的文章,因此,查看了Java中的字符是如何存储的,即char数据类型。在此将学到的知识做一个总结。

一、char数据类型 

char类型最初用于表示Unicode字符集中的一个字符,但是随着Unicode标准的不断发展,其字符集不断扩展,表示的字符随之增加,已经超出了16位的char类型可以表示的范围(65535),现今,char类型用于表示一个代码单元。有些Unicode字符需要使用一个代码单元表示,有些Unicdoe字符需要两个代码单元表示。关于代码单元的概念,下文会详细介绍,这里先有一个印象即可。

1. 字面量值

字面量值需要单引号''括起来,单引号中必须有值,其形式如下:

  • 单个Unicode字符,最常见的形式,例如,'A''中'
  • 转义序列\u,范围\u0000~\uFFFF,例如, '\u2122' 表示字符'\u03C0'表示字符'π'
  • 特殊字符的转义序列,例如'\n'表示换行,'\''表示单引号。

转义字符,一般是不可打印的或者与语言的语法字符产生了冲突。

二、Unicode字符集

1. 字符集和编码规则

我们经常会听到Unicode、UTF-8、UTF-16这些术语,然而,它们是完全不同的概念。Unicode是字符集,UTF-8、UTF-16是编码规则,具体概念如下:

字符集:为每一个「字符」分配了一个唯一的 ID或者编号(称为为码位 / 码点 Code Point)
编码规则:将「编号」转换为字节序列的规则

 例如,‘中’ 的码点如下

 其使用不同编码规则,进行编码的结果如下

2. Unicode字符集


Java设计之初Unicode字符集中的字符个数还不到65536的一半,所以使用16位的char类型完全可以表示所有字符,但是,随着中、日、韩等其它字符的加入,导致Unicode字符集中的字符个数超过了65535,此时char类型已经无法表示Unicode字符集中的所有字符了。

我们先介绍一些必备的基础知识。

码点表示了一个字符的ID或者编号,在Unicode标准中,采用十六进制书写,并加上前缀U+,例如U+0041(转换为十进制即65),表示字母A的码点。

把Unicoee字符分为17个平面,每个平面包含不同种类的字符。

基本的多语言平面,码点范围U+0000~U+FFFF,表示了我们各个国家常用的字符,也是开始的char类型可以表示的字符。

其他平面(1到16号平面),码点范围U+10000~U+10FFFF,表示辅助字符,例如我们的不常用的繁体字等等,char类型无法直接表示这些字符,例如,char = '‘𝕆’ 会编译报错( 𝕆,一个数学符号,Unicdoe字符码点 U+1D546)


那么,char如何表示码点在U+10000~U+10FFFF之间的Unicode字符呢?

它借鉴了UTF-16编码规则。

UTF-16使用不同长度的编码表示所有Unicode字符。在基本的多语言平面中,使用16位表示一个字符,称为代码单元,而其他平面的辅助字符需要使用32位,也就是一对代码单元表示一个字符。

U+D800~U+DBFF表示第一个代码单元,U+DC00~U+DFFF表示第二个代码单元。

U+D800~U+DFFF,这一段码点称为替换区域,可以看出它属于基本的多语言平面(U+0000~U+FFFF)的范围,为了避免产生歧义或冲突,替换区域的码点没有没配给任何字符。

假设为替换区域码点分配了字符,就无法判断该码点是表示一个字符,还是辅助字符的第一个代码单元或第二个代码单元。

具体让我们看一下如何表示字符 ‘⑪’ (Unicdoe字符码点 U+1D546)?

第一个代码单元:D800到DBFF
1101 1000 0000 0000
1101 1011 1111 1111
110110XXXXXXXXXX 可以编码10位二进制数

第二个代码单元:DC00到DFFF
1101 1100 0000 0000
1101 1111 1111 1111
110111XXXXXXXXXX 可以编码10位二进制数

U+10000到U+10FFFF 可以看出转换成二进制树最多有21位,但是我们加起来最多可以编码20位二进制数,怎么办?

将范围偏移-10000,范围变成了U+0000到U+FFFFF,如此,就满足20位编码了。

⑪ U+1D546 偏移后U+D546

1101 0101 0100 0110

后十位“01 0100 0110"放入第二个代码单元110111XXXXXXXXXX:1101 1101 0100 0110,对应的十六进制数:DD46

前十位(不足十位首部补0)00001101 01 放入第一个代码单元110110XXXXXXXXXX:1101 1000 0011 0101,对应的十六进制数是:D835

因此,⑪,U+1D546使用两个代码单元表示:D835 DD46

我们在程序中如何存储码点在U+10000到U+10FFFF之间的字符呢?

直接存储字符字面量值或者转义序列\u,编译报错。很容易理解char类型16位正好只能存储一个代码单元,而该字符需要两个代码单元表示,无法用char类型直接表示该字符。

总结:现在,char类型用于描述一个代码单元对于基本的多语言平面中的字符(码点范围U+0000到U+FFFF,不包含替换区域)可以使用一个代码单元表示,也就是一个char值。对于其他平面的字符(码点范围U+10000到U+10FFFF)可以使用两个代码单元表示,也就是两个char值。

严格来说,char类型可以表示使用一个代码单元表示的Unicode字符,char类型无法直接表示两个代码单元表示的字符。

怎么办,对于需要两个代码单元表示的字符就不能使用了吗?
不是的,我们可以把他们放在字符串类型中,字符串是由字符构成的,它把U+D800到U+DBFF之间的代码单元解读为字符的第一个代码单元,把U+DC00到U+DFFFF解读为字符的第二个代码单元,然后把两个代码单元解读为一个字符。它把U+0000到U+FFFF之间除去替换区域(U+D800到U +DFFF)的代码单元解读为一个字符。

String str = "\uD835\uDD46";


最后的建议,程序中最好不要使用char类型,除非你想处理代码单元。像操作Unicode字符,可以使用Java中的String类型。

 public static void main(String[] args) {

        // 字符串中放入需要两个码点表示的字符'𝕆'
        String  str = "𝕆A";

        // 获取索引为0的代码单元,而不是字符
        char ch0 = str.charAt(0);
        char ch1 = str.charAt(1);
        char ch2 = str.charAt(2);

        System.out.println(ch0);
        System.out.println(ch1);
        System.out.println(ch2);

    }

有些字符不能被正确的处理


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1150219.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode | 17.04.消失的数字和189.旋转数组

LeetCode | 17.04.消失的数字和189.旋转数组 文章目录 LeetCode | 17.04.消失的数字和189.旋转数组17.04.消失的数字方法一:方法二:方法三:方法二的代码方法三的代码 189.旋转数组思路一思路二思路三 17.04.消失的数字 OJ链接 这里题目要求…

②CPU - 运算器、控制器 【软考-软件设计师考点】

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ ②CPU - 运算器、控制器 【软考-软件设计师考点…

基于python的app程式开发

安装的库文件: 运行代码: # -*- coding:utf-8 -*- from kivy.app import App class HelloApp(App):pass if __name__ __main__:HelloApp().run() 结果画面:

PTA 病毒溯源(树)

题目 病毒容易发生变异。某种病毒可以通过突变产生若干变异的毒株,而这些变异的病毒又可能被诱发突变产生第二代变异,如此继续不断变化。 现给定一些病毒之间的变异关系,要求你找出其中最长的一条变异链。 在此假设给出的变异都是由突变引起…

数据分类保护敏感数据

数据分类是一个过程,用于发现敏感内容,并对关键数据进行分组,以便进一步配置 DLP。数据分类过程分析组织的数据存储库,以便根据文件的内容和上下文有效地将文件分类为不同的类别,并协助配置适当的安全控制级别以符合数…

leetcode:1207. 独一无二的出现次数(python3解法)

难度:简单 给你一个整数数组 arr,请你帮忙统计数组中每个数的出现次数。 如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false。 示例 1: 输入:arr [1,2,2,1,1,3] 输出:true 解释&…

一站式解决安全问题

端玛科技致力于攻克困难的应用软件安全问题,我们的解决方案以安全标准、安全教育和安全风险评估三大支柱为安全SDLC的基础,这三大支柱相互依存,创建了一个可重复的、安全的软件开发生态系统。 主要业务范围:关注整个软件开发过程…

WebRTC介绍

什么是WebRTC WebRTC(Web Real-Time Communications)是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流…

react实现列表增删改查的小demo(class组件版)

前言 react的语法上就是比vue麻烦不少,既然要开手动挡,那就开吧,一个基础的demo 效果图 列表 新增弹窗 编辑弹框 新增一条数据后的效果 代码 根组件 index.jsx import React, { Component,createRef} from react import withRouter from ../../utils/withRouter import G…

什么是同步通信?什么是异步通信?两者的优缺点是什么?

什么是通信? 通信是指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递。从广义上来说,通信是指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法、任意媒质,将信息从某方准确安全地传送到另方。在出现电波传递通信…

Element-UI el-row 排版样式错乱

Element-UI el-row el-col 配合el-form 表单使用&#xff0c;造成样式的错乱。 如图&#xff1a; ![在这里插入图片描述](https://img-blog.csdnimg.cn/13520a35e3d44e4099b5bc04d5201f29.png#pic_center 大概就是这个&#xff0c;代码&#xff1a; <el-row gutter"…

coturn服务器的搭建

Window下搭建coturn服务器&#xff1a; 准备材料&#xff1a; 1、安装Cygwin&#xff0c;地址&#xff1a;https://cygwin.com/install.html 由于Window无法直接部署coturn&#xff0c;因此需要下载安装Cygwin在Window上部署Linux虚拟环境。 在安装的时候需要安装几下packe…

vue实现记事本(无样式版)

实现了增、删功能&#xff0c;任务统计&#xff0c;全删除功能。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

【达梦数据库】DM概述、数据定义(表空间管理、用户管理、模式管理、表管理)

文章目录 DM概述数据定义表空间管理1. 创建表空间2. 修改表空间3. 删除表空间 用户管理1. 创建用户2. 修改用户3. 删除用户 模式管理1. 创建模式(2种方法)2. 设置当前模式3. 删除模式 表管理1. 创建表2. 修改表3. 删除表 文章有点点长&#xff0c;可以先收藏哦&#xff0c;如果…

ECCV 22丨BUTD-DETR:图像和点云的语言标定Transformer

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://arxiv.org/abs/2112.08879[1] 主页链接&#xff1a;https://github.com/nickgkan/butd\_detr[2] 摘要&#xff1a; 在二维和三维场景中&#xff0c;大多数模型的任务都是将指涉…

Kafka生产问题总结及性能优化实践

Kafka可视化管理工具kafka-manager 安装及基本使用可参考&#xff1a;https://www.cnblogs.com/dadonggg/p/8205302.html 线上环境规划 JVM参数设置 kafka是scala语言开发&#xff0c;运行在JVM上&#xff0c;需要对JVM参数合理设置&#xff0c;参看JVM调优专题 修改bin/kaf…

算法通关村第十二关黄金挑战——最长公共前缀问题解析

大家好&#xff0c;我是怒码少年小码。 最长公共前缀 LeetCode 14&#xff1a;编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”]输出&#xff…

CSS+Javascript+Html日历控件

最近&#xff0c;因需要用HTMLJAVASCRIPTCSS实现了一个日历控件&#xff0c;效果如下&#xff1a; 单击上月、下月进行日历切换。当前日期在日历中变颜色标注显示。还是老老套路、老方法&#xff0c;分HMLCSSJAVASCRIPT三部分代码。 一、html代码 <h1>学习计划</h1…

HubSpot CRM是什么?如何添加、使用呢?

HubSpot CRM是一款强大的客户关系管理工具&#xff0c;它不仅简化了销售和市场营销过程&#xff0c;还提供了多种功能&#xff0c;有助于增强客户互动、提高销售效率和提供更多的洞察信息。 今天运营坛将带领大家深入了解HubSpot CRM&#xff0c;涵盖了它的定义、使用流程、添…

国产芯片vs“国际水平”,有距离也有超越!

当前&#xff0c;国产芯片正在迎来全新的发展阶段。国产终端芯片性能怎么样&#xff0c;与国际主流产品相比&#xff0c;表现如何&#xff1f;今天笔者就针对目前热度较高的四款国产CPU进行参数分析与性能跑分横向对比。 此次国产芯片评测型号分别是海光C86-3250、龙芯3A5000H…