gpt4 book ai didi

java - "Negating"字符串给出了意外的行为

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:39:56 24 4
gpt4 key购买 nike

我在研究 String 及其构造函数时发现了一些我无法解释的行为。

我创建了以下方法

public static String negate(String s) {
byte[] b = s.getBytes();
for (int i = 0; i < b.length; i++) {
b[i] = (byte)(~b[i] + 1);
}
System.out.println(Arrays.toString(b));
return new String(b);
}

它只是对每个 byte 进行 2 的补码,并为此返回一个新的 String。像这样调用它时

System.out.println(negate("Hello"));

我得到了输出

[-72, -101, -108, -108, -111]
�����

我想这很好,因为没有负 ASCII 值。
但是当我像这样嵌套调用时

System.out.println(negate(negate("Hello")));

我的输出是这样的

[-72, -101, -108, -108, -111]
[17, 65, 67, 17, 65, 67, 17, 65, 67, 17, 65, 67, 17, 65, 67]
ACACACACAC // 5 groups of 3 characters (1 ctrl-char and "AC")

我希望输出与我的输入字符串 "Hello" 完全匹配,但我却得到了这个。为什么?这也会发生在所有其他输入字符串上。嵌套之后,输入中的每个字符都变成 AC

我走得更远,创建了一个做同样事情的方法,但只使用原始 byte 数组

public static byte[] n(byte[] b) {
for (int i = 0; i < b.length; i++) {
b[i] = (byte)(~b[i] + 1);
}
System.out.println(Arrays.toString(b));
return b;
}

这里的输出符合预期。对于

System.out.println(new String(n(n("Hello".getBytes()))));

我明白了

[-72, -101, -108, -108, -111]
[72, 101, 108, 108, 111]
Hello

所以我想这与 String 的创建方式有关,因为它仅在我调用 negate 时发生,该实例已获得负值 字节

我什至沿着类树走下去查看内部类,但我找不到这种行为的来源。

也在 String 的文档中以下段落可能是一种解释:

The behavior of this constructor when the given bytes are not valid in the default charset is unspecified

谁能告诉我为什么会这样以及这里到底发生了什么?

最佳答案

问题是您正在获取反转字节并尝试将它们解释为默认字符集中的有效字节流(请记住,字符不是字节)。因此,正如您引用的字符串构造函数文档告诉您的那样,结果是未指定的,并且可能涉及纠错、删除无效值等。自然地,这是一个有损过程,并且将其逆转不会让您恢复原状原始字符串。

如果您获取字节并对它们进行双重否定,将中间字节转换为字符串,您将得到原始结果。

这个例子演示了 new String(/*invalid bytes*/) 的有损特性:

String s = "Hello";
byte[] b = s.getBytes();
for (int i = 0; i < b.length; i++) {
b[i] = (byte)(~b[i] + 1);
}
// Show the negated bytes
System.out.println(Arrays.toString(b));
String s2 = new String(b);
// Show the bytes of the string constructed from them; note they're not the same
System.out.println(Arrays.toString(s2.getBytes()));

在我认为默认为 UTF-8 的系统上,我得到:

[-72, -101, -108, -108, -111][-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67]

注意当我获取无效字节流、从中生成一个字符串,然后获取该字符串的字节时发生了什么。

关于java - "Negating"字符串给出了意外的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43258608/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com