Java [11]紧跟字符串拼写char []到byte []

问题描述 投票:2回答:2

在过去的两天里,我一直在阅读关于编写Unicode Java 9 compact Strings的信息。但有一点我不明白。

关于字节数据类型

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

问题

1)。为什么Java没有像char无符号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相同。

我尝试过像codepoint 128048这样的最难的例子,我在String.value变量中看到像这样的字节数组。

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

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

对不起,如果这个问题很简单,对不起任何打字英语都不是我的自然语言,非常感谢。

java string ascii java-9 extended-ascii
2个回答
5
投票

为什么Java没有像char无符号16位那样实现它?我的意思是它将在0.256的范围内,因为从0到127只能保持Ascii值,但是如果我将值设置为200,则会发生什么情况会延长ascii将溢出到-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的不同解释,而包含位模式byte11001000的iso-latin-1解释是字符È

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相同”时,你应该问自己,它是如何知道11001000的位模式byte首先是-56

System.out.println(value[0]);

与普通的计算机算术相比,byte(或int)转换为String,实际上是昂贵的操作。这种转换操作经常被忽略,因为它被定义为打印byte的默认方式,但并不比转换为String将值解释为无符号数量更自然。为了进一步阅读,我推荐Two's complement


2
投票

这是因为并非字符串中的所有字节都被解释为相同。这取决于字符串的character encoding

例:

  • 如果字符串是UTF-8字符串,则其字符大小为8位。
  • 在UTF-16字符串中,其字符大小为16位。
  • 等等...

这意味着,如果要将字符串表示为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

回到这个问题,开发人员这样做的动机是减少字符串的内存占用。并非所有字符串都使用char提供的所有16位。

编辑:Code here

© www.soinside.com 2019 - 2024. All rights reserved.