Java中字符串与byte[]的相互转换

Java中String使用char[]数组以16位定长对每个字符进行Unicode编码,想要用byte[]类型处理字符串时,需要在String类型与byte[]类型间相互转换。

其实没什么值得写的,调2个方法就可以了。

String转byte[]

不指定编码方式

使用String类型的getBytes()方法,以当前运行环境下的默认编码方式将每个char元素转换为byte[]

1
2
System.out.println(Arrays.toString("12ab我们".getBytes()));
System.out.println(new String("12ab我们".getBytes()));

得到结果

1
2
[49, 50, 97, 98, -26, -120, -111, -28, -69, -84]
12ab我们
  • 可以猜出本主机默认编码方式为UTF-8,将汉字编为了3个byte,而数字和英文字母都是1个byte
  • 在另一环境中,编码结果可能不同
  • 不推荐使用该方式

指定编码字符集1

getBytes(String charsetName),以字符串的方式指定编码字符集,可以指定为”UTF-8”和”UTF-16”等。Java中一般采用大端字节序,所以我们使用”UTF-16BE”。

1
2
3
4
5
6
7
8
byte[] myByteArr;
try {
myByteArr = "12ab我们".getBytes("UTF-16BE");
System.out.println(Arrays.toString(myByteArr));
System.out.println(new String(myByteArr));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

结果

1
2
[0, 49, 0, 50, 0, 97, 0, 98, 98, 17, 78, -20]
1 2 a bbN�
  • UTF-16采用2字节或4字节对字符编码,可以看到这里无论是数字、英文字母、汉字,都是用了2字节。
  • 在String的构造器中没能用byte[]生成想要的字符串,这是因为构造器转换时可能使用的是UTF-8编码(解码)方式
  • 需要做异常检查

指定编码字符集2

getBytes(Charset charset),提供Charset类参数,分别用UTF-16高端字节序和UTF-8测试

1
2
3
4
System.out.println(Arrays.toString("12ab我们".getBytes(StandardCharsets.UTF_16BE)));
System.out.println(new String("12ab我们".getBytes(StandardCharsets.UTF_16BE)));
System.out.println(Arrays.toString("12ab我们".getBytes(StandardCharsets.UTF_8)));
System.out.println(new String("12ab我们".getBytes(StandardCharsets.UTF_8)));

结果

1
2
3
4
[0, 49, 0, 50, 0, 97, 0, 98, 98, 17, 78, -20]
1 2 a bbN�
[49, 50, 97, 98, -26, -120, -111, -28, -69, -84]
12ab我们
  • 结果与前面的以字符串的方式指定编码字符集的方法相同。区别是,前者函数参数为字符串,这里是Charset类
  • 此方法不会抛异常
  • 需要用到1.7开始提供的StandardCharsets类

byte[]转String

String类型构造器

以byte[]数组为变量构造字符串,其实前面的例子中已经用到过了。

与String转byte[]的对应,byte[]转String也可以有3种。

  • String(byte[] byteArr)
  • String(byte[] byteArr, String charsetName)
  • String(byte[] byteArr, Charset charset)

(1)当不指定字符集时,使用构造器默认的字符集。String(byte[] byteArr)

1
2
3
byte[] byteArr1 = "12ab我们".getBytes();
String str1 = new String(byteArr1);
System.out.println(str1);

结果

1
12ab我们

(2)用字符串指定字符集(需要做异常处理)String(byte[] byteArr, String charsetName)

1
2
3
4
5
6
7
8
byte[] byteArr2 = new byte[0];
try {
byteArr2 = "12ab我们".getBytes("UTF-16BE");
String str2 = new String(byteArr2,"UTF-16BE");
System.out.println(str2);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

结果

1
12ab我们

(3)用Charset类参数指定,并与不指定时做比较String(byte[] byteArr, Charset charset)

1
2
3
4
5
byte[] byteArr3 = "12ab我们".getBytes(StandardCharsets.UTF_16BE);
String str3 = new String(byteArr3);
System.out.println(str3);
str3 = new String(byteArr3, StandardCharsets.UTF_16BE);
System.out.println(str3);

结果

1
2
 1 2 a bbN�
12ab我们

显然使用UTF-16编码的字节数组,需要在String构造处指定字符集才能正确得被转换为String类型