String.valueOf引发的错误
背景
近日在配合客户端调试的时候,客户端无法解析restful返回的失败返回值,需要服务器端配合解决,该问题,查看了服务端的log,返回值以json格式正常返回了,没有异常,那问题出在哪里呢?怀疑是客户端解析问题导致。
分析问题
查看了客户端的解析返回值的代码,发现疑点,客户端使用String.valueOf(byte []),将收到的byte []转换了为String,这就存在问题,因为String提供了valueOf转义,但是没有提供针对byte []的转义,见下:
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(Object obj)
针对byte [] 的对象,只能调用String valueOf(Object obj)来进行转义,但是这个方法式依赖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方法,于是乎,我们得到的是类名称+@+散列码十六进制,我们拿着这种格式的字符串,再去做操作,必然是失败的结果。
问题如何解决
解决该问题,其实也很简单,就是用new String(byte bytes[])构建对象就可以了,在这个构造函数中,可以通过,StringCoding.decode,将byte[]转码为char[],而String本省就是底层用final char value[],进行存储的。
例子见下:
byte[] bytes = new byte[]{'c','d'};
String s1 = String.valueOf(bytes);
System.out.println(s1);
String s2 = new String(bytes);
System.out.println(s2);
返回值是 :
s1: [B@3c48403
s2: cd
结语
通过该问题的分析,我们知道,编码不是只是为了编码,不能应付,而是要对自己使用的技术的一些基本原理和一些注意事项有一定的了解,才能避免一些低级错误的产生。