用Java中的字节数组序列化类
我有一个Java中带有字节数组的类。当我序列化和反序列化类的对象时,字节数组的值正在改变 我如何解决这个问题 请参见示例代码:用Java中的字节数组序列化类,java,serialization,bytearray,deserialization,Java,Serialization,Bytearray,Deserialization,我有一个Java中带有字节数组的类。当我序列化和反序列化类的对象时,字节数组的值正在改变 我如何解决这个问题 请参见示例代码: public class Test implements Serializable{ private static final long serialVersionUID = 3455892176538865707L; public byte[] datakey; public static void main(String[] args) { byte[
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
字节数组的值没有改变。您只是在打印数组的
toString()
表示
将使用java.lang.Object
中的默认toString()
实现
由于初始数组和反序列化数组不是相同的对象(它们是具有相同内容的两个独立对象),因此它们将具有不同的hashCode()
Java中的数组不会覆盖equals()
和hashCode()
您应该使用
Arrays.toString()
来打印数组的内容。当您将对象传递给System.out.println()
方法时,将调用该对象的toString()
方法
toString方法的默认实现如下所示:
getClass().getName()+'@'+Integer.toHexString(hashCode())
在这两个输出中,getClass().getName()
返回[B
但Integer.toHexString(hashCode())
返回不同的值。现在唯一的方法是hashCode()序列化对象的
与反序列化对象的不同。这正是发生的情况。虽然没有正式提及,hashCode()
的默认实现似乎是返回对象的内部地址。hashCode()
方法的javadocs说明:
在合理可行的情况下,hashCode方法由
类对象不会为不同的对象返回不同的整数
通常通过转换
对象转换为整数,但此实现技术不适用
JavaTM编程语言要求。)
由于序列化对象在反序列化时很可能会加载到不同的地址,因此会得到不同的
hashCode
值,因此,toString
的不同输出仍然无法解释输出中打印的hashCode值为何不同?如果正在序列化的数组与正在序列化的数组相同e-序列化,hashcode不是应该相等吗?因为数组不重写hashcode()和equals()Java中的方法。@Crazyjavahacking你确定吗?毕竟,数组必须使用类在内部实现。@Crazyjavahacking好吧,如果它们不重写equals和hashCode,就更有理由相信它们使用的是hashCode方法的默认实现,这解释了为什么我们在输出中得到两个不同的值。s请看我的答案。@Crazyjavahacking请看这个。sunil,请看我的答案,以获得序列化和反序列化对象的不同字符串表示形式的详细解释。您没有打印字节数组的内容。@sunilzacharias请阅读:getClass().getName()
返回[B
实际上。@EJP.同意.已编辑。哈希代码不同的原因是对象不同。不同的对象必须加载到不同的地址,但这是不相关的。但不正确。它应该读为“因为反序列化对象与序列化对象不同,因此它将具有不同的哈希代码,即因此,toString()。
@EJP同意不同的输出。但我猜这是从两条语句中间接暗示出来的:1.将使用默认的hashCode方法;2.反序列化时,序列化对象将加载到不同的地址。因此,这意味着对象是不同的。