Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java &引用;否定;字符串会产生意外的行为_Java_Arrays_String - Fatal编程技术网

Java &引用;否定;字符串会产生意外的行为

Java &引用;否定;字符串会产生意外的行为,java,arrays,string,Java,Arrays,String,我在玩String及其构造函数,发现了一些无法解释的行为 我创建了以下方法 公共静态字符串否定(字符串s){ 字节[]b=s.getBytes(); for(int i=0;i

我在玩
String
及其构造函数,发现了一些无法解释的行为

我创建了以下方法

公共静态字符串否定(字符串s){
字节[]b=s.getBytes();
for(int i=0;i
它只是对每个
字节进行2的补码,并为其返回一个新的
字符串。当你这样称呼它的时候

System.out.println(否定(“Hello”);
我得到了一个

[-72,-101,-108,-108,-111]
�����
我想这很好,因为没有负的ASCII值。
但是当我像这样嵌套调用时

System.out.println(否定(否定(“Hello”));
我的输出是这样的

[-72,-101,-108,-108,-111]
[17, 65, 67, 17, 65, 67, 17, 65, 67, 17, 65, 67, 17, 65, 67]
ACAC//5组3个字符(1个ctrl字符和“AC”)
我希望输出与我的输入字符串“Hello”
完全匹配,但结果却是这样。为什么?这也会发生在其他输入字符串中。嵌套后,输入中的每个字符都会变成
AC

我更进一步,创建了一个做同样事情的方法,但只使用原始
字节
数组

公共静态字节[]n(字节[]b){
for(int i=0;i
这里的输出与预期一致。为了

System.out.println(新字符串n(n(“Hello.getBytes())));
我明白了

[-72,-101,-108,-108,-111]
[72, 101, 108, 108, 111]
你好
所以我想这与
字符串
s的创建方式有关,因为它只在我调用
否定
时发生,而实例已经得到了负的
字节
s

我甚至走下类树查看内部类,但我找不到这种行为的来源

在的文件中还有以下段落可能是一种解释:

当给定字节在默认字符集中无效时,此构造函数的行为未指定


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

你“否定”一个字符,它就无效了。然后得到占位符
(U+FFFD)。在这一点上,一切都被破坏了。然后你“否定”它,然后你从每个占位符字符中得到你的
AC

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

如果您获取字节并对其进行双反运算,而不将中间字节转换为字符串,您将返回原始结果

此示例演示了
新字符串(/*无效字节*/)
的有损性质:

String s=“你好”;
字节[]b=s.getBytes();
for(int i=0;i
在我的系统上(我认为默认为UTF-8),我得到:

[-72, -101, -108, -108, -111] [-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67] [-72, -101, -108, -108, -111] [-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67]
请注意,当我获取无效字节流,从中生成一个字符串,然后获取该字符串的字节时发生了什么。

嗯,是的-您试图将实际不是编码文本的任意字节解释为编码文本。我强烈建议您不要这样做。如果您使用映射256个字节的字符集(例如ISO-8859-1),它与第一种方法一起工作,并且您所做的任何事情都不涉及ASCII。可以设置为,但其用途非常明确:根据计算机操作系统用户的当前设置而变化。在我工作过的任何领域都没有用。这要看情况而定。UTF-8不是所有地方的默认字符集。不,但这里就是这样,我不想把它延伸到“编码是如何工作的”答案。 [-72, -101, -108, -108, -111] [-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67]