2 回答

TA贡献1982条经验 获得超2个赞
为什么Java没有像char unsigned 16 bits那样实现它?我的意思是它会在 0.256 的范围内,因为从 0 到 127 我只能保存一个 Ascii 值,但是如果我将值设置为 200 会发生什么,扩展的 ascii 会溢出到 -56。
Java 的原始数据类型在 25 年前的 Java 1.0 中得到了解决。不到两年前,Java 9 中引入了紧凑字符串。这个新特性只是一个实现细节,并不能证明 Java 类型系统的根本变化是合理的。
除此之外,您正在查看存储在一个字节中的数据的一种解释。为了表示 iso-latin-1 单位,将相同的数据解释为 Java 内置的 signedbyte是否会导致正数或负数完全无关紧要。
同样,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
这两个数字,-56和200只是位模式的不同解释,而包含位模式的11001000iso-latin-1 解释是字符。byte11001000È
值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].
在类中使用byte[]数组的优点String是,现在可以选择解释,当所有字符都可以用这种编码表示时使用 iso-latin-1,否则使用 utf-16。
可能的数字解释与字符串无关。但是,当你问“Java 怎么知道 -56 值与 200 相同”时,你应该问自己,它是如何知道11001000abyte的位模式-56在首位的?
System.out.println(value[0]);
与普通计算机算术相比,a byte(或 an int)到 a的转换实际上是一个昂贵的操作String。这种转换操作经常被忽略,因为它已被定义为打印 a 的默认方式,但并不比将值解释为无符号数量byte的转换更自然。String为了进一步阅读,我推荐二进制补码。

TA贡献1909条经验 获得超7个赞
这是因为并非字符串中的所有字节都被解释为相同的。这取决于字符串的字符编码。
例子:
如果字符串是 UTF-8 字符串,则其字符大小为 8 位。
在 UTF-16 字符串中,其字符大小为 16 位。
ETC...
这意味着,如果要将字符串表示为 UTF-8,则字符将通过一次读取 1 个字节来生成;如果是 16 位,则字符将通过一次读取 2 个字节来生成。
看这段代码:data
使用 UTF-8 和 UTF-16 将单字节数组转换为字符串。
byte[] data = new byte[] {97, 98, 99, 100};
System.out.println(new String(data, StandardCharsets.UTF_8));
System.out.println(new String(data, StandardCharsets.UTF_16));
这段代码的输出是:
abcd // 4 bytes = 4 chars, 1 byte per char
慢捤 // 4 bytes = 2 chars, 2 byte per char
回到这个问题,开发人员这样做的动机是减少字符串的内存占用。并非所有字符串都使用所有 16 位 achar报价。
添加回答
举报