简体   繁体   中英

Serializing a class with Byte Array in Java

I have a class with byte array in 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.

The default toString() implementation from java.lang.Object will be used.

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() . Arrays in Java does not override equals() and hashCode() .

You should use Arrays.toString() to print the content of the array instead.

When you pass an object to the System.out.println() method, the toString() method of that object will be called.

The default implementation of the toString method looks like this :

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

In both your outputs, getClass().getName() returns [B but Integer.toHexString(hashCode()) returns different values. Now the only way this can happen is that hashCode() of the serialized object is different from that of the de-serialized object. 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. The javadocs for the hashCode() method says this :

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (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.)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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