我在Java中有一个带字节数组的类。当我序列化和反序列化类的对象时,字节数组的值正在改变。
我该如何解决这个问题?
请参阅示例代码:
public class Test implements Serializable{
private static final long serialVersionUID = 3455892176538865707L;
public byte[] datakey;
public static void main(String[] args) {
byte[] key=new byte[16];
Random rn = new Random(); //Trying to randomize the byte array to use as a cryptographic key
rn.nextBytes(key);
Test test = new Test();
test.datakey=key;
System.out.println("Byte Array Before serialization : "+test.datakey);
test.serializeTest(test);
Test loadedtest=test.deserializeTest();
System.out.println("Byte Array After deserialization : "+loadedtest.datakey);
}
public void serializeTest(Test test)
{
FileOutputStream fos;
try {
fos = new FileOutputStream("test.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(test);
oos.flush();
oos.close();;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Test deserializeTest()
{
Test test=null;
String f="test.out";
try
{
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
test = (Test)ois.readObject();
ois.close();
fis.close();
}
catch(FileNotFoundException ex)
{
ex.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return test;
}
}
输出:
Byte Array Before serialization : [B@15db9742
Byte Array After deserialization : [B@75b84c92
答案 0 :(得分:5)
字节数组的值不会改变。您只是打印数组的toString()
表示。
将使用toString()
的默认java.lang.Object
实施。
因为初始和反序列化的数组不是相同的对象(它们是具有相同内容的两个独立对象),所以它们将具有不同的hashCode()
。 Java中的数组不会覆盖equals()
和hashCode()
。
您应该使用Arrays.toString()
来打印数组的内容。
答案 1 :(得分:2)
将对象传递给System.out.println()
方法时,将调用该对象的toString()
方法。
toString方法的默认实现如下所示:
getClass().getName() + '@' + Integer.toHexString(hashCode())
在两个输出中,getClass().getName()
都会返回[B
,但Integer.toHexString(hashCode())
会返回不同的值。现在,唯一可能发生的方法是序列化对象的hashCode()
与反序列化对象的hashCode()
不同。这正是发生的事情。虽然没有正式提及,但hashCode()
的默认实现似乎返回了对象的内部地址。 hashCode
方法的javadoc说明了这一点:
尽可能合理实用,由hashCode方法定义 class Object确实为不同的对象返回不同的整数。 (这个 通常通过转换内部地址来实现 将对象转换为整数,但这种实现技术不是 JavaTM编程语言所要求的。)
由于序列化对象很可能在反序列化时被加载到不同的地址,因此您会得到不同的toString
值,因此{{1}}的输出不同