20241209
写在前面:事件起因是 比较BigDecimal的类型时,出现了浮点数的问题,equal 和 compareTo出现了不同的结果。本着刨根问底的技术原则,开始往下刨。在搜索了相关资料之后 发现有些介绍中 说到了 ==比较的是ASCII码,嘿,勾起了我的兴趣,我得去看看具体情况。
上文链接:
哪一步和ASCII码有关系? Unicode和ASCII什么关系
ASCII 是 Unicode 的一个子集,因此在 Java 编程过程中,ASCII 在 Unicode 的处理过程中起到了基础作用。具体来说,ASCII 主要与 Unicode 兼容部分的字符(即范围在 0 到 127 之间的字符)相关联。
ASCII 与 Unicode 的关系:
- ASCII (American Standard Code for Information Interchange) 是一个 7 位编码标准,最初用于表示英文字母、数字、标点符号和一些控制字符。ASCII 能表示 128 个字符(
0x00
到0x7F
)。 - Unicode 是一个更为广泛的字符集,能够表示几乎所有现代语言的字符、符号、表情符号等。Unicode 包含了多个字符范围,其中包括 ASCII 字符集。
ASCII 在 Unicode 中的位置
- 在 Unicode 中,0 到 127 的码点(即
U+0000
到U+007F
)完全与 ASCII 相同。换句话说,所有 ASCII 字符(包括英文字母、数字、常见符号等)在 Unicode 中的表示是相同的,Unicode 的这些字符码点与 ASCII 编码一致。
ASCII 和 Unicode 的关系示例
字符 | ASCII 码 | Unicode 码点(U+形式) | 描述 |
---|---|---|---|
A | 65 | U+0041 | 大写字母 A |
a | 97 | U+0061 | 小写字母 a |
0 | 48 | U+0030 | 数字 0 |
! | 33 | U+0021 | 感叹号 |
| 32 | U+0020 | 空格 |
- ASCII 码点范围(0x00 到 0x7F) 与 Unicode 码点范围(U+0000 到 U+007F) 完全一致。
- 例如:
A
的 ASCII 码是 65,对应的 Unicode 码点是U+0041
。a
的 ASCII 码是 97,对应的 Unicode 码点是U+0061
。
ASCII 与 Unicode 处理过程中的关系:
- Java 字符串处理:
- ASCII 字符串(例如
"hello"
)直接使用 7 位 ASCII 编码。在 Java 中,Java 字符串是基于 Unicode 编码的,但是 ASCII 字符是 Unicode 编码的一部分。所以,对于 ASCII 字符,Java 使用的是与 ASCII 完全相同的 Unicode 表示(即U+0000
到U+007F
范围内的字符)。
- ASCII 字符串(例如
- 编译与字节码:
- 当你在 Java 中编写字符串如
"hello"
时,字符串中的每个字符(例如'h'
)会先被转换为对应的 Unicode 编码,如果字符在 ASCII 范围内,则它的 Unicode 码点与 ASCII 码点相同。 - 在编译过程中,编译器将这些字符串按照 Unicode 编码存储在字节码中。Java 字节码本身并不直接存储字符的 ASCII 值,而是存储 Unicode 值。
- 当你在 Java 中编写字符串如
- JVM 和 Unicode 执行:
- JVM 在运行时会将这些字符的 Unicode 码点解释成适合本地平台的格式(通常是 UTF-16),并将其处理成机器码执行。
- 如果字符串中包含 ASCII 字符,它们会被直接当作其 Unicode 值进行处理。
- 计算机显示:
- 最终,计算机根据显示设备的字符集(如字体)渲染 Unicode 字符。如果字符位于 ASCII 范围内,显示设备可以直接使用与 ASCII 相同的编码渲染这些字符。
ASCII 和 Unicode 如何协同工作:
-
对于 ASCII 字符(即 0x00 到 0x7F),Unicode 是完全兼容的。它们之间的差异仅体现在字符的范围。ASCII 只包括英语字母、数字和一些符号,而 Unicode 包含全球所有书写系统的字符。
-
在 Java 中,所有字符串都是基于 Unicode 编码的,即使它们包含的是 ASCII 字符。对于 ASCII 字符,Unicode 会使用与其相同的编码。
-
例如:
字符串
"hello"
在 Java 内部会被表示为:
- Unicode 码点:
U+0068 U+0065 U+006C U+006C U+006F
。 - 对应的 ASCII 码:
104 101 108 108 111
。
- Unicode 码点:
总结:
- ASCII 是 Unicode 的子集,其中 Unicode 的前 128 个字符(
U+0000
到U+007F
)与 ASCII 完全相同。 - Java 使用 Unicode 处理字符串,即使是包含 ASCII 字符的字符串,仍然会按照 Unicode 编码存储和处理。
- ASCII 仅在 Java 处理 基本拉丁字符(例如英文字母、数字和常见符号)时直接参与,而 Unicode 可以处理更多语言和符号。
通过这种兼容性,Java 可以跨平台处理不同字符集的字符串,而不需要担心 ASCII 和其他字符集的差异。