字节转字符串 Java SDK中lang包String类中代码求详解
/* 1 java 的字符串实际上字符数组,而java的字符都是unicode 编码的,(一般用到的是每个字符占16位,2个字节,
* 构成一个无符号数)。
* 2 而这个构造方法是给定一个字节数组(每个字节是8位),给定高位字节,给定起始偏移量,给定长度来构成一
* 个字符串。
* 3 因为字节数组每个元素只有8位,而变成字符要16位,这个高8位,由参数hibyte以int型给出,(代码里看到只
* 用其低8位,)用它和字节数组的每个元素组成一个16位的无符号整数(代表一个字符)。
*/
public String(byte ascii[], int hibyte, int offset, int count) {
// 4 判定给定的参数是否有效。可在原码里看这个方法。
checkBounds(ascii, offset, count);
char value[] = new char[count];//5 定义字符数组,(注意:是构造方法里的局部变量,)长度就是count.
// 6 当hibyte==0时,只需要把byte转换成char。
// 如果字节>=0, 可以直接强转,即value[i]=(char)ascii[i+offset];
// 但如果字节<0, 这样会有问题。比如字节是-31,其二进制表示是 1110 0001,强转成char变成
// 了 1111 1111 1110 0001,char是无符号数,这个-31变成 char是 65505了。这样不对了。实际
// 上我们要的是 0000 0000 1110 0001,这个是225。 所以代码里用:
// value[i] = (char) (ascii[i + offset] & 0xff);
// 这样的语句,就是把类似-31转换为225,而不是 65505。
if (hibyte == 0) {
for (int i = count ; i-- > 0 ;) {
value[i] = (char) (ascii[i + offset] & 0xff);
}
}
// 7 当hibyte不为零时,需要把其低8位变成char的高8位,再与字节元素组成一个16位的char。
// 所以代码里有hibyte <<= 8; 左移8位的代码。之后用它与字节的8位进行“或”运算,最后强转为
// char类型。
else {
hibyte <<= 8;
for (int i = count ; i-- > 0 ;) {
value[i] = (char) (hibyte
[解决办法]
(ascii[i + offset] & 0xff));
}
}
//8 最后,用局部变量给成员变量赋值。
this.offset = 0;
this.count = count;
this.value = value;
}