简体   繁体   English

在Java中使用字节数组序列化类

[英]Serializing a class with Byte Array in Java

I have a class with byte array in Java. 我在Java中有一个带字节数组的类。 When I serialize and deserialize the object of the class, the value of the Byte Array is changing. 当我序列化和反序列化类的对象时,字节数组的值正在改变。

How can I address this problem? 我该如何解决这个问题?

Please see the example code: 请参阅示例代码:

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;
}
}

Output of this: 输出:

Byte Array Before serialization : [B@15db9742
Byte Array After deserialization : [B@75b84c92

The value of the byte array is not changing. 字节数组的值不会改变。 You are just printing the toString() representation of the array. 您只是打印数组的toString()表示。

The default toString() implementation from java.lang.Object will be used. 将使用java.lang.Object的默认toString()实现。

Because the initial and deserialized arrays are not the same objects (they are two independent objects with the same content), they will have different hashCode() . 因为初始和反序列化的数组不是相同的对象(它们是具有相同内容的两个独立对象),所以它们将具有不同的hashCode() Arrays in Java does not override equals() and hashCode() . Java中的数组不会覆盖equals()hashCode()

You should use Arrays.toString() to print the content of the array instead. 您应该使用Arrays.toString()来打印数组的内容。

When you pass an object to the System.out.println() method, the toString() method of that object will be called. 将对象传递给System.out.println()方法时,将调用该对象的toString()方法。

The default implementation of the toString method looks like this : toString方法的默认实现如下所示:

getClass().getName() + '@' + Integer.toHexString(hashCode())

In both your outputs, getClass().getName() returns [B but Integer.toHexString(hashCode()) returns different values. 在两个输出中, getClass().getName()返回[B但是Integer.toHexString(hashCode())返回不同的值。 Now the only way this can happen is that hashCode() of the serialized object is different from that of the de-serialized object. 现在,唯一可能发生的方法是序列化对象的hashCode()与反序列化对象的hashCode()不同。 This is exactly what happens. 这正是发生的事情。 While not officially mentioned, the default implementation of the hashCode() seems to be returning the internal address of the object. 虽然没有正式提及,但hashCode()的默认实现似乎是返回对象的内部地址。 The javadocs for the hashCode() method says this : hashCode()方法的javadoc说:

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. 尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.) (这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要此实现技术。)

Since the serialized object will most likely be loaded into a different address when de-serialized, you get different hashCode values and thus, different outputs from toString 由于序列化对象很可能在反序列化时被加载到不同的地址,因此您获得不同的hashCode值,因此来自toString不同输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM