我正在玩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);
}
它只是做了2对每个byte
补充,并返回一个新的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
s的创建方式,因为它只有当我叫negate
与已经得到了负byte
秒的情况下发生?
我甚至走下类树看内部类,但我无法找到这种行为来自哪里。
另外在String的文档有以下段落,这可能是一个解释:
此构造函数时给出的字节是不是在默认字符集有效的行为是不确定的
灿有人告诉我为什么它是这样的,到底发生了什么?
嗯,是的 - 你试图解释这仿佛他们正在编码的文本实际上并没有编码的文本任意字节。我强烈建议你不要这样做。 –
如果使用映射256个字节(如ISO-8859-1例如)字符集,它的工作原理与第一种方法 – aurya
而且,没有什么你正在做包括ASCII。 [String.getBytes()](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#getBytes())可以作出但其目的是非常具体的:为了根据计算机操作系统用户的当前设置而有所不同。在我工作的任何域中都没有用。 –