Java 11 紧凑字符串 char[] 到 byte[] 背后的魔法

标签 java string ascii java-9 extended-ascii

在过去的两天里,我一直在阅读有关编码 Unicode Java 9 紧凑字符串的内容,我感觉好多了。但有一点我不明白。

关于字节数据类型

1).是8位存储范围是-128到127

问题

1).为什么Java没有像char unsigned 16位那样实现它?我的意思是它的范围是 0.256,因为从 0 到 127 我只能保存一个 Ascii 值,但是如果我将值设置为 200,扩展的 ascii 会溢出到 -56,会发生什么。

2).负值是否意味着什么?我的意思是我尝试了一个使用 Java 11 的简单示例

final char value = (char)200;//in byte would overflow
final String stringValue = new String(new char[]{value});
System.out.println(stringValue);//THE SAME VALUE OF JAVA 8

我已经检查了 String.value 变量,我看到了一个字节数组

System.out.println(value[0]);//-56

与之前出现的相同问题,-56 是否意味着其他语言中的(负值),检测到此溢出返回到值 200? Java怎么知道-56值与char中的200相同。

我尝试过最难的例子,比如代码点 128048,我在 String.value 变量中看到了这样的字节数组。

0 = 61 
1 = -40
2 = 48
3 = -36

我知道这个代码点需要 4 个字节,但我知道如何将 char[] 转换为 byte[] 但我不知道 String 如何处理这个 byte[] 数据。

抱歉,如果这个问题很简单,抱歉,任何键入英语都不是我的自然语言,非常感谢。

最佳答案

Why Java didn't implement it like char unsigned 16 bits? i mean it would be in a range of 0.256 because from 0 to 127 only can i hold a Ascii value but what would happen if i set the value 200 a extended ascii would overflow to -56.

四分之一个世纪前,Java 的原始数据类型已在 Java 1.0 中解决。不到两年前,Java 9 中引入了紧凑字符串。这个新功能仅仅是一个实现细节,并不能证明对 Java 类型系统进行根本性改变是合理的。

除此之外,您正在查看存储在字节中的数据的一种解释。为了表示 iso-latin-1 单位,将相同的数据解释为 Java 内置的有符号 byte 会得到正数还是负数是完全无关的。

同样,Java 的 I/O API 允许将文件读入 byte[] 数组并将 byte[] 数组写回文件,这两个操作已经足以无损地复制文件,无论其文件格式如何,这在解释其内容时都是相关的。

因此,自 Java 1.1 起,以下内容有效:

byte[] bytes = "È".getBytes("iso-8859-1");
System.out.println(bytes[0]);
System.out.println(bytes[0] & 0xff);
-56
200

这两个数字,-56200 只是位模式 11001000 的不同解释,而 iso-latin-1 解释为包含位模式 11001000字节是字符È

char 值也只是对两个字节数量的解释,即 UTF-16 代码单元。同样,char[] 数组是计算机内存中具有标准解释的字节序列。

我们还可以用这种方式解释其他字节序列。

StringBuilder sb = new StringBuilder().appendCodePoint(128048);
byte[] array = new byte[4];
StandardCharsets.UTF_16LE.newEncoder()
    .encode(CharBuffer.wrap(sb), ByteBuffer.wrap(array), true);
System.out.println(Arrays.toString(array));

将打印您看到的值,[61, -40, 48, -36]

String 类中使用 byte[] 数组的优点是,现在可以选择解释,在所有情况下使用 iso-latin-1字符可以用此编码表示,否则可以用 utf-16 表示。

可能的数字解释与字符串无关。但是,当您问“Java 如何知道 -56 值与 200 相同”时,您应该问自己,它如何知道 byte 的位模式 11001000 code> 首先是 -56 吗?

System.out.println(value[0]);
与普通计算机算术相比,

承担着实际上昂贵的操作,即将字节(或int)转换为字符串。这种转换操作经常被忽视,因为它已被定义为打印字节的默认方式,但并不比转换为将值解释为字符串的字符串更自然。无签名数量。如需进一步阅读,我推荐Two's complement .

关于Java 11 紧凑字符串 char[] 到 byte[] 背后的魔法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55002968/

相关文章:

java - 如何在 Java 9 中通过模块获取 jar 文件名?

java - 如何将输入的字符串存储到不同的变量中?

c - 在 strftime 中使用指针目标 (C)

php - HTML ASCII 实体等效的特殊字符

java - 为什么我可以使用 US Ascii Locale 来处理大写/小写的德语变音符号?

JavaPreparedStatement 表的注释

java - 用户名和密码问题 : Input recognition - Java

java - JXTable 中的自定义 header 渲染器?

mysql - 替换 MySQL 列中的某些文本

java - 在 Itextpdf 中设置字体大小