Java语言中将字符串和字节数组之间相互转换的场景很多,比如我们常见的,socketChannel,netty,RocketMQ这类的应用在数据传输过程中都需要将字串转换为Byte数组,然后再将Byte数据转换为String。比如RSA,DES之类的加解密场景,也是需要对转换为Byte数据后进行。本文总结了Byte[]和String之间的转换原理以及实现。
首先来一段代码作为引入:
public static void main(String[] args) {
System.out.println("println 0:"+new String("test".getBytes()));
System.out.println("println 1:"+String.valueOf("test".getBytes()));
System.out.println("println 2"+String.valueOf("test".getBytes().toString()));
}
输出结果:
println 0:test
println 1:[B@6d06d69c
println 2:[B@7852e922
输出结果大家还是很有意思的,整体来说因为"println 0"输出的是"test"的字符串;"println 1"输出的是Byte[]数组的Object的toString值;"println 1"输出的是"String"的toString值。之所以会出现这么有趣的结果,跟Byte转换为String的几个关键函数有关。这部分的源码实现很简洁,我们先来看一下。
1.new String()
String(String original)
String(char value[])
String(char value[], int offset, int count)
String(int[] codePoints, int offset, int count)
String(byte bytes[], int offset, int length, String charsetName)
String(byte bytes[], int offset, int length, Charset charset)
String(byte bytes[], String charsetName)
String(byte bytes[], Charset charset)
String(byte bytes[], int offset, int length)
String(byte bytes[])
String(StringBuffer buffer)
String(StringBuilder builder)
String(char[] value, boolean share)
通过String的构造方法可以看出String主要关注点就是处理,String,char[],byte[]这三个类型。
2.String.valueOf()
String valueOf(Object obj)
String valueOf(char data[])
String valueOf(char data[], int offset, int count)
String valueOf(boolean b)
String valueOf(char c)
String valueOf(int i)
String valueOf(long l)
String valueOf(float f)
String valueOf(double d)
String.valueOf在接收参数后会先调用参数的toString方法,然后调用newString方法生产一个字符串。 因为String提供了valueOf转义,但是没有提供针对byte []的转义,所以当String.valueOf(Byte[])时参数是被视为object进行处理。这就引出了我们的第三个关键方法,Object 的toString是怎么实现的问题。
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
//Object的的toString方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
因为Object的toString方法,默认返回类名称+@+散列码十六进制,这个很显然不是我们预期的结果。
总结 String和Byte之间的转换是个很有趣的问题,通过一系列看起来很有条理的方法,最终的结果却与我们预期的结果大相径庭。其中所涉及的问题确实最能反映设计者考虑问题的思路的。比如虽然通过一系列的源码解读我们梳理出来String和Byte专业的原理和实现