用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[

我有一个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

字节数组的值没有改变。您只是在打印数组的
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.反序列化时,序列化对象将加载到不同的地址。因此,这意味着对象是不同的。